单文档模式(父窗口里边只有一个子窗口)
将创建窗口的前四个步骤封装成一个函数CreateParent(),这个是创建父窗口的。
里边的实例 hInstance 应该在程序最前面声明一个全局变量来存放。
HINSTANCE g_hInstance, 在入口函数的第一步就是:g_hInstance = hInstance.
窗口句柄也该放在程序前面声明:
HWND hWndParent;
HWND hWndChild;
子窗口 的CreateWindows() 里边 记得加上 父窗口的句柄,关联起来。
而且子窗口的 lpszClassName 不能跟 父窗口一样。
各自要有各自的回调函数,不然 子窗口的消息会应该同化父窗口的,反之亦然。
欧敏鑫代码
可以实现一些简单功能,关闭子窗口其实是隐藏子窗口,右键后恢复。
或者关闭后,可多次创建子窗口。
#include <windows.h>
#include <stdio.h>
#include <math.h>
#pragma warning (disable : 4244)
HINSTANCE g_hInstance;//声明一个全局变量 来装创建的实例
HWND hWndParent;
HWND hWndChild;
LRESULT CALLBACK ParentWindowProc( HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
LRESULT CALLBACK ChildWindowProc( HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
void CreateParent()
{
WNDCLASS wc ={0};
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
// wc.hbrBackground = ::CreateSolidBrush(0xffffff);
wc.hbrBackground = (HBRUSH)::GetStockObject(DKGRAY_BRUSH);
wc.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wc.hIcon = ::LoadIcon(NULL,IDI_QUESTION);
wc.hInstance = g_hInstance;
wc.lpfnWndProc = ParentWindowProc; ///////////////回调函数
wc. = "asdf";
wc.lpszMenuName = NULL;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
ATOM atom =::RegisterClass(&wc);
if(atom == 0) return;
hWndParent = ::CreateWindow(wc.lpszClassName,"first bolld",WS_OVERLAPPEDWINDOW,10,10,800,600,NULL,NULL,g_hInstance,NULL);
if(hWndParent == NULL) return;
// DWORD dword = ::GetLastError();
::ShowWindow(hWndParent,SW_SHOW);
::UpdateWindow(hWndParent);
}
void CreateChild()
{
WNDCLASS wc ={0};
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
// wc.hbrBackground = ::CreateSolidBrush(0xffffff);
wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wc.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wc.hIcon = ::LoadIcon(NULL,IDI_QUESTION);
wc.hInstance = g_hInstance;
wc.lpfnWndProc = ChildWindowProc; /////////////////////回调函数
wc.lpszClassName = "aa";
wc.lpszMenuName = NULL;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
ATOM atom =::RegisterClass(&wc);
DWORD i = ::GetLastError();
// if(atom == 0) return;
hWndChild = ::CreateWindow(wc.lpszClassName,"first bolld",WS_OVERLAPPEDWINDOW |
WS_CHILD,10,10,400,300,hWndParent,NULL,g_hInstance,NULL);
if(hWndChild == NULL) return;
// DWORD dword = ::GetLastError();
::ShowWindow(hWndChild,SW_SHOW);
::UpdateWindow(hWndChild);
}
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
g_hInstance = hInstance;
CreateParent();
CreateChild();
MSG msg;
while(::GetMessage(&msg,NULL,0,0))
{
::DispatchMessage(&msg);
}
return msg.wParam;
}
//父 回调
LRESULT CALLBACK ParentWindowProc( HWND hWnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_KEYDOWN:
{
if(wParam == VK_ESCAPE)
::DestroyWindow(hWnd);
}
break;
case WM_CLOSE:
{
::DestroyWindow(hWnd);
}
break;
case WM_RBUTTONDOWN:
{
::ShowWindow(hWndChild,SW_SHOW);
}break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return 0;
}
/////////////子 回调
LRESULT CALLBACK ChildWindowProc( HWND hWnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_KEYDOWN:
{
if(wParam == VK_ESCAPE)
::DestroyWindow(hWnd);
}
break;
case WM_CLOSE:
{
::ShowWindow(hWnd,SW_HIDE);
}
break;
// case WM_DESTROY:
// ::PostQuitMessage(0);
// break;
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return 0;
}