Подclass: кнопка в пользовательском classе с использованием SetWindowSubclass

Я пытаюсь написать class, чтобы обрабатывать создание кнопки и ее сообщения внутри. Я хочу сохранить весь код, содержащийся внутри самого classа. Это может быть просто или невозможно, поскольку я относительно новичок в Winapi и C ++, используя vb.net гораздо шире. Я не смог найти пример, который сделал это кажущееся простое преобразование. Я нашел примеры, предлагающие использовать альтернативный API или использовать SetWindowLongPtr, мне сказали, что SetWindowSubclass – лучший вариант. Мой код:

#pragma once #include  #include  #include  using namespace std; class button { public: bool initialize(); buttton(int x, int y, int length, int width, LPCWSTR text, HWND parent, HINSTANCE hInstance); // This is the constructor private: LPCWSTR text = L"Button"; int height = 25; int width = 100; int x = 0; int y = 0; HWND parent; HWND thisHandle; HINSTANCE thisInstance; bool initialized = false; LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); }; button::button(int x, int y, int height, int width, LPCWSTR text, HWND parent, HINSTANCE hInstance) { this->x = x; this->y = y; this->height = height; this->width = width; this->text = text; this->parent = parent; thisInstance = hInstance; } bool button::initialize() { thisHandle = CreateWindowW( L"BUTTON", // Predefined class; Unicode assumed text, // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_CLIPSIBLINGS | BS_NOTIFY, // Styles x, // x position y, // y position width, // Button width height, // Button height parent, // Parent window NULL, // No ID. thisInstance, NULL); // Pointer not needed. if (!thisHandle) { return false; } initialized = true; //Problem Code**** SetWindowSubclass(thisHandle, mySubClassProc, 1, 0); //**** return true; } LRESULT CALLBACK button::mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { //Code handling messages here. } } 

Это вызывает ошибку:

аргумент типа «LRESULT (__stdcall button :: *) (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)” несовместим с параметром типа “SUBCLASSPROC”

Я надеюсь, что кто-то может объяснить простое решение или предложить альтернативу в Winapi, так как я хочу изучать родные windows и C ++ и не полагаться на дополнительные библиотеки.

Вы пытаетесь использовать метод нестатического classа в качестве обратного вызова подclassа. Это не сработает, потому что метод нестатического classа скрывает this параметр, который API не сможет передать.

Чтобы сделать то, что вы пытаетесь, вы должны удалить this параметр (вместо this вы можете использовать параметр SetWindowSubclass() ):

  1. используя метод статического classа :

     class button { public: bool initialize(); ... private: ... static LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); }; bool button::initialize() { ... SetWindowSubclass(thisHandle, mySubClassProc, 1, (DWORD_PTR) this); return true; } LRESULT CALLBACK button::mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { button *pThis = (button*) dwRefData; //Code handling messages here. } 
  2. используя функцию, не являющуюся членом :

     class button { public: bool initialize(); ... }; LRESULT CALLBACK myButtonSubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { button *pBtn = (button*) dwRefData; //Code handling messages here. } bool button::initialize() { ... SetWindowSubclass(thisHandle, myButtonSubClassProc, 1, (DWORD_PTR) this); return true; }