CreateWindowEx(..., lParam); Как его получить? GetWindowLong? - Не пойму никак какой из парметров. Помогите! Спасибо.
сталобыть в обработчике WM_CREATE берешь lpParam, в нем буит указатель на CREATESTRUCT, в которой твой lParam идет по смещенею 0
просто ситуация немного не такая стандартная у меня есть класс для обертки АПИ создания окна есть статическая фукция класса которая является функцией переходником для вызова нужного виртуального члена класса WndProc. Так вот в этом переходнике необходимо знать адрес экземпляра класса которому принадлежит текущий описатель окна. Я этот адрес передаю в структуре, адрес которой указываю при создании окна. Теперь - у меня в переходнике есть описатель окна, но как теперь получить адрес объекта? Юзаю GetWindowLong(hWnd, GWL_USERDATA) но увы нифига - возврат - 0;( Код (Text): LRESULT CustomWidow::WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam) { CRITICAL_SECTION cSection; ResourceTypeInt *ResInt; InitializeCriticalSection(&cSection); EnterCriticalSection(&cSection); ResInt = (ResourceTypeInt *)GetWindowLong(hWnd, GWL_USERDATA); //? ==0 LeaveCriticalSection(&cSection); return ResInt->Object->InternalProc(hWnd, msg, wparam, lparam); }
Вот пример. Код (Text): Базовый класс для MDI-окон #define MDIVIEWPROPERTY "CIDDMDIView" class CIDDMDIView { public: HWND m_hWnd; CIDDMDIView(); virtual ~CIDDMDIView(); static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); ... virtual LRESULT OnMsg(UINT iMsg, WPARAM wParam, LPARAM lParam); ... }; Создание окна bool CIDDMDIView::Create(char* szClass, char* szTitle, UINT nID, UINT nIndex) { BOOL bIsActiveMax = FALSE; ... m_hWnd = CreateMDIWindow(szClass, szTitle, MDIS_ALLCHILDSTYLES|WS_VISIBLE|WS_CLIPCHILDREN|(bIsActiveMax?WS_MAXIMIZE:0), CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, g_hMDIClient, GetModuleHandle(NULL), (LPARAM)this); ... return true; } Статическая функция окна (общая для всех производных классов) LRESULT CALLBACK CIDDMDIView::WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { LPCREATESTRUCT lpcs = NULL; LPMDICREATESTRUCT lpmcs = NULL; CIDDMDIView* pOwner = NULL; LRESULT lResult = 0; if (iMsg == WM_CREATE) { lpcs = (LPCREATESTRUCT)lParam; lpmcs = (LPMDICREATESTRUCT)lpcs->lpCreateParams; pOwner = (CIDDMDIView*)lpmcs->lParam; if (!pOwner || !SetProp(hWnd, MDIVIEWPROPERTY, (HANDLE)pOwner)) { ... return FALSE; } pOwner->m_hWnd = hWnd; } else pOwner = (CIDDMDIView*)GetProp(hWnd, MDIVIEWPROPERTY); if (pOwner) { lResult = pOwner->OnMsg(iMsg, wParam, lParam); if (iMsg == WM_DESTROY) { ... RemoveProp(hWnd, MDIVIEWPROPERTY); pOwner->m_hWnd = NULL; delete pOwner; } return lResult; } return DefMDIChildProc(hWnd, iMsg, wParam, lParam); } Виртуальная функция окна, перегружаемая в производном классе LRESULT CIDDMDIView::OnMsg(UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) { ... } return DefMDIChildProc(m_hWnd, iMsg, wParam, lParam); }
При создании окна передаётся this: Код (Text): void TMyWndClass::CreateEx (...) { // registration, etc. //... CreateWindowEx (..., this); } При получении WM_CREATE этот самый this присобачивается к HWND: Код (Text): ... SetWindowLong (hWnd, GWL_USERDATA, (LONG) pWnd); ... При получении сообщения иного чем WM_CREATE смотрим если this уже присобачен, тогда вызываем виртуальную процедуру окна, если нет, то тогда DefWindowProc(). Вот приблизительно так: Код (Text): LRESULT CALLBACK MyWndClassProc (HWND hWnd, UINT uiMsg, WPARAM wp, LPARAM lp) { TMyWndClass* pWnd; if (uiMsg == WM_CREATE) { // Retrieve 'this' // pWnd = ((TMyWndClass**) lp) [0]; // Attach 'this' to HWND // SetWindowLong (hWnd, GWL_USERDATA, (LONG) pWnd); // Invoke window creation routine (virtual) // pWnd -> OnWmCreate (hWnd); // // Base class method for this ^^^ stores input HWND as class member, // so it is locked in during lifetime of a window. Also, derived class must // call base class version first, so HWND always will be initialized before // derived class can begin its own initialization (creating child controls, etc.) return 0; } else if ((pWnd = (TMyWndClass*) GetWindowLong (hWnd, GWL_USERDATA)) != NULL) { // Invoke virtual message mapping routine // LRESULT lRes = pWnd -> MsgMap (uiMsg, wp, lp); // // Base class method for this ^^^ calls DefWindowProc () as needed // Usually, it is called last (before returning) if message was not processed by // a class if (uiMsg == WM_DESTROY) { // Detach 'this' from HWND // SetWindowLong (hWnd, GWL_USERDATA, 0); } return lRes; } // Code goes here before WM_CREATE and after WM_DESTROY // return DefWindowProc (hWnd, uiMsg, wp, lp); }