前文/问题
我试图做一个相当简单的工具来帮助调试变量值.因为它是完全自我包含在课堂内是我的目标.最终产品我可以在类中使用ShowThisValue(无论如何)中的函数.
我遇到的问题是,如果可能的话,我无法弄清楚课程内的程序.这是短版本,有问题.
-Code再次更新11/29 / 13-
– 我现在把它放在自己的项目中.
[main.cpp中]
viewvars TEST; // global TEST.CreateTestWindow(hThisInstance); // in WinMain() right before ShowWindow(hwnd,nFunsterStil);
[viewvars.h]整个更新
class viewvars { private: HWND hWindow; // the window,a pointer to LRESULT WindowProc(UINT message,WPARAM wParam,LPARAM lParam); static LRESULT CALLBACK ThisWindowProc(HWND hwnd,UINT message,LPARAM lParam); public: viewvars(); // blank constructor int CreateTestWindow(HINSTANCE hInst); }; // blank constructor viewvars::viewvars() {} // create the window int viewvars::CreateTestWindow(HINSTANCE hInst) { // variables char thisClassName[] = "viewVars"; MSG msg; WNDCLASS wincl; // check for class info and modify the info if (!GetClassInfo(hInst,thisClassName,&wincl)) { wincl.style = 0; wincl.hInstance = hInst; wincl.lpszClassName = thisClassName; wincl.lpfnWndProc = &ThisWindowProc; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hIcon = NULL; wincl.hCursor = NULL; wincl.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; wincl.lpszMenuName = NULL; if (RegisterClass(&wincl) == 0) { MessageBox(NULL,"The window class Failed to register.","Error",0); return -1; } } // create window hWindow = CreateWindow(thisClassName,"Test",WS_POPUP | WS_CLIPCHILDREN,10,200,NULL,hInst,this); if (hWindow == NULL) { MessageBox(NULL,"Problem creating the window.",0); return -1; } // show window ShowWindow(hWindow,TRUE); // message loop while (GetMessage(&msg,hWindow,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // then quit window? DestroyWindow(hWindow); hWindow = NULL; return msg.wParam; } // window proc LRESULT CALLBACK viewvars::ThisWindowProc(HWND hwnd,LPARAM lParam) { MessageBox(NULL,"Has it gone this far?","Bench",0); // variable viewvars *view; // ???? if (message == WM_NCCREATE) { CREATESTRUCT *cs = (CREATESTRUCT*)lParam; view = (viewvars*) cs->lpCreateParams; SetLastError(0); if (SetWindowLongPtr(hwnd,GWL_USERDATA,(LONG_PTR) view) == 0) { if (GetLastError() != 0) { MessageBox(NULL,"There has been an error near here.",0); return FALSE; } } } else { view = (viewvars*) GetWindowLongPtr(hwnd,GWL_USERDATA); } if (view) return view->WindowProc(message,wParam,lParam); MessageBox(NULL,"If shown,the above statement did not return,and the statement below did.",0); return DefWindowProc(hwnd,message,lParam); } LRESULT viewvars::WindowProc(UINT message,LPARAM lParam) { // you can access non-static members in here... MessageBox(NULL,"Made it to window proc.",0); switch (message) { case WM_PAINT: return 0; break; case WM_DESTROY: PostQuitMessage(0); return 0; break; default: MessageBox(NULL,"DefWindowProc Returned.",0); return DefWindowProc(hWindow,lParam); break; } }
消息框按照以下顺序显示:
有没有这样呢?
>使其进行窗口处理
>返回DefWindowProc
有没有这样呢? // 重复?
>使其进行窗口处理
>返回DefWindowProc
>创建窗口的问题
感谢您的帮助到目前为止.你知道问题在哪里吗?
主消息循环不能在您的类中,特别是不在“CreateTestWindow”函数中,因为您的线程将收到使GetMessage返回0的WM_QUIT消息之前不会从该函数返回.
这是您的viewvars类的简单实现.关键点:
> Window Proc是一个静态成员.
> Window Proc和对象之间的链接是通过
使用GWLP_USERDATA.见SetWindowLongPtr.
> DTOR类破坏窗口,如果它仍然存在. WM_DESTROY
消息将HWND成员设置为0.
>将OnMsgXXX方法添加到类很简单:declare / define then
并且只需使用“this”指针从WindowProc调用它们
存储在GWLP_USERDATA中.
编辑:
>根据陈先生的建议,HWND早期绑定到对象(在WM_NCCREATE中),以便在窗口创建期间允许消息处理程序作为方法.
我改变了创作风格,展现了窗口,并能够移动它.
// VIEWVARS.H class viewvars { public: static viewvars* CreateTestWindow( HINSTANCE hInstance ); viewvars() : m_hWnd( 0 ) {} ~viewvars(); private: static LRESULT CALLBACK WindowProc( HWND hwnd,UINT uMsg,LPARAM lParam ); static const char * m_pszClassName; HWND m_hWnd; }; // VIEWVARS.CPP #include "viewvars.h" const char * viewvars::m_pszClassName = "viewvars"; viewvars * viewvars::CreateTestWindow( HINSTANCE hInst ) { WNDCLASS wincl; if (!GetClassInfo(hInst,m_pszClassName,&wincl)) { wincl.style = 0; wincl.hInstance = hInst; wincl.lpszClassName = m_pszClassName; wincl.lpfnWndProc = WindowProc; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hIcon = NULL; wincl.hCursor = NULL; wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); wincl.lpszMenuName = NULL; if (RegisterClass(&wincl) == 0) { MessageBox(NULL,0); return 0; } } viewvars * pviewvars = new viewvars; HWND hWnd = CreateWindow( m_pszClassName,WS_VISIBLE | WS_OVERLAPPED,50,pviewvars ); if ( hWnd == NULL ) { delete pviewvars; MessageBox(NULL,0); return 0; } return pviewvars; } LRESULT CALLBACK viewvars::WindowProc( HWND hwnd,LPARAM lParam ) { switch ( uMsg ) { case WM_NCCREATE: { CREATESTRUCT * pcs = (CREATESTRUCT*)lParam; viewvars * pviewvars = (viewvars*)pcs->lpCreateParams; pviewvars->m_hWnd = hwnd; SetWindowLongPtr( hwnd,GWLP_USERDATA,(LONG)pcs->lpCreateParams ); return TRUE; } case WM_DESTROY: { viewvars * pviewvars = (viewvars *)GetWindowLongPtr( hwnd,GWLP_USERDATA ); if ( pviewvars ) pviewvars->m_hWnd = 0; break; } default: return DefWindowProc( hwnd,uMsg,lParam ); } return 0; } viewvars::~viewvars() { if ( m_hWnd ) DestroyWindow( m_hWnd ); }
最后,一个“主要”的样本,但请注意,这里没有办法结束这个过程.应该通过常规代码(另一个窗口)来关注.
// MAIN.CPP #include <Windows.h> #include "viewvars.h" int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { viewvars * pviewvars = viewvars::CreateTestWindow( hInstance ); if ( pviewvars == 0 ) return 0; BOOL bRet; MSG msg; while( (bRet = GetMessage( &msg,0 )) != 0) { if (bRet == -1) { // handle the error and possibly exit } else { TranslateMessage(&msg); DispatchMessage(&msg); } } delete pviewvars; return 0; }