简单的封装一个类,但是发现窗口类的注册和窗口创建的代码不能放到同一个函数里面。放到同一个函数里面就会提示创建失败。代码如下: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函数里面的时候就发现无法创建窗口。
{
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函数里面的时候就发现无法创建窗口。
解决方案 »
- Debug下没问题,Release出问题!
- 向edit控件里设数字用哪个方法?
- 想做一个软件,但又不晓得做什么好。郁闷啊!
- 如何在自定义消息中传入一个字符数组(10个字符)?
- 高手进来看看,给解释一下,下列语句的意思?
- extern "c"的疑惑
- 简单的问题,VC里是否可以使用控件数组?怎么做,从VB转到VC,什么都不会
- LISTCONTROL怪问题~~~~
- 急,大虾们,我写的onmousenter,onmouseleave怎么没有反应?有几行代码
- Message Maps 中为什么找不到 OnWindowPosChanging ?
- 一条类似九曲黄河般的封闭曲线,已知其各点坐标,希望能以线条填充
- vs2010编写出来MFC为什么这么大?
不要console
它会给你一个样板,看看就清楚了
额 这个是没问题的。建立的就是windows应用程序。
{
initMainWnd();
}这个地方AppInit还没有形成,调用initMainWnd不行,就按照人家规定
在InitInstance()里放initMainWnd()可以没错
{
if (gApp != 0)
{ return gApp->msgProc(msg, wParam, lParam);
}
else
{
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
应该在msgProc函数的case WM_CREATE 里注册窗口。
应该在go里放Loop圈,而且你Loop圈里的条件好像有些异样。要想学WinApi,看看《Windows程序设计》,经典中的经典。
不是不可以放到同一个函数上
只是调用方式的问题
你直接
app.go();
那是一点问题也没有
假如使用了指针
AppInit *app = new AppInit();
or
gApp = &app
gApp->go();
也不行
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代码
{ }
} 看看