简单的封装一个类,但是发现窗口类的注册和窗口创建的代码不能放到同一个函数里面。放到同一个函数里面就会提示创建失败。代码如下:class AppInit 
{
public:
AppInit(HINSTANCE instance);
~AppInit();

void initMainWnd();
LRESULT CALLBACK msgProc(UINT msg, WPARAM wParam, LPARAM lParam);
int go(); HWND getHwnd();private:
HWND m_hWnd;
HINSTANCE m_hInstance;
};
AppInit *gApp = 0;
LRESULT CALLBACK MainWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{

if (gApp != 0)
{ return gApp->msgProc(msg, wParam, lParam);
}
else
{
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}LRESULT CALLBACK AppInit::msgProc( UINT msg, WPARAM wParam, LPARAM lParam )
{ switch (msg)
{ case WM_CLOSE:
DestroyWindow(m_hWnd);
return 0;
case  WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(m_hWnd, msg, wParam, lParam);
}
return 0;
}//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void AppInit::initMainWnd()
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_ERROR);
wc.hInstance = m_hInstance;
wc.lpfnWndProc = MainWndProc;
wc.lpszClassName = "CLASS";
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;

if ( !RegisterClass(&wc) )
{
MessageBox(0, "RegisterClass FAILED!", 0, 0);
PostQuitMessage(0);
}
m_hWnd = CreateWindow("CLASS", "Tetris", WS_OVERLAPPEDWINDOW
&~WS_MAXIMIZEBOX&~WS_THICKFRAME, 200, 100, 900, 500, NULL,
NULL, m_hInstance, NULL); if ( !m_hWnd )
{
MessageBox(0, "CreateWindow FAILED!", 0, 0);
PostQuitMessage(0);
}

}//---------------------------------------------------------------------------
AppInit::AppInit(HINSTANCE instance):m_hWnd(0),m_hInstance(instance)
{
initMainWnd();
}//---------------------------------------------------------------------------
AppInit::~AppInit()
{}//---------------------------------------------------------------------------
HWND AppInit::getHwnd()
{
return m_hWnd;
}
//.................
int AppInit::go()
{
ShowWindow(m_hWnd, SW_SHOW);
UpdateWindow(m_hWnd);//若放到initMainWnd则失去第一次处理WM_PAINT消息的机会
MSG msg;
msg.message = WM_NULL;
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else//Dx代码
{ }
}
return (int)msg.wParam;
}int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  AppInit app(hInstance);
gApp =&app;
gApp->go();
return 0;
}当我把initMainWnd里面内容放到go函数里面的时候就发现无法创建窗口。

解决方案 »

  1.   

    vs建立一个windows 程序 不要mfc
     不要console 
    它会给你一个样板,看看就清楚了
      

  2.   


    额 这个是没问题的。建立的就是windows应用程序。
      

  3.   

    AppInit::AppInit(HINSTANCE instance):m_hWnd(0),m_hInstance(instance)
    {
        initMainWnd();
    }这个地方AppInit还没有形成,调用initMainWnd不行,就按照人家规定
    在InitInstance()里放initMainWnd()可以没错
      

  4.   

    问题在这个函数LRESULT CALLBACK MainWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
        
        if (gApp != 0)
        {        return gApp->msgProc(msg, wParam, lParam);    
        }
        else
        {
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
    }
      

  5.   

    Window的WM_CREATE消息的处理上。
      

  6.   

    微软设定的怎么发窗口讯息,怎么接收是有规矩的。
    应该在msgProc函数的case WM_CREATE 里注册窗口。
    应该在go里放Loop圈,而且你Loop圈里的条件好像有些异样。要想学WinApi,看看《Windows程序设计》,经典中的经典。
      

  7.   

    刚刚试了一下
    不是不可以放到同一个函数上
    只是调用方式的问题
    你直接
    app.go();
    那是一点问题也没有
    假如使用了指针
    AppInit *app = new AppInit();
    or
    gApp = &app
    gApp->go();
    也不行
      

  8.   

    while 循环改成
    while (GetMessage(&msg, NULL, 0, 0))
    {
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    }而非
    while (msg.message != WM_QUIT) 

    if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    {
    TranslateMessage(&msg); DispatchMessage(&msg);

    else//Dx代码  
    { }
    } 看看