C++中的子窗口问题
我在关闭子窗口时出现了问题,主窗口也退出。C++中的子窗口问题
我是这个编程的新手。
正确的代码:
/** @file MainWindow.cpp
@author Andro Bondoc
@date 2011-02-11
*/
/** @file MainWindow.cpp @author Andro Bondoc @date 2011-02-11 */
#include "tray.h"
#define WM_USER_SHELLICON WM_USER + 1
HWND hWnd, Button, LoadNew, TextBox;
HINSTANCE hInst;
HICON hMainIcon;
HMENU hPopMenu;
NOTIFYICONDATA structNID;
long PASCAL WndProcParent(HWND,UINT,UINT,LONG);
long PASCAL WndProcChild(HWND,UINT,UINT,LONG);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASS wc, ws;
hInst = hInstance;
if(!hPrevInstance)
{
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProcParent;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));//LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wc.lpszMenuName = NULL;
wc.lpszClassName = "Data Retriever Parent";
RegisterClass(&wc);
ws.style = CS_HREDRAW | CS_VREDRAW;
ws.lpfnWndProc = WndProcChild;
ws.cbClsExtra = 0;
ws.cbWndExtra = 0;
ws.hInstance = hInstance;
ws.hIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));//LoadIcon(NULL,IDI_APPLICATION);
ws.hCursor = LoadCursor(NULL,IDC_ARROW);
ws.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
ws.lpszMenuName = NULL;
ws.lpszClassName = "Data Retriever Child";
RegisterClass(&ws);
}
hWnd = CreateWindowEx(0, wc.lpszClassName, "Data Retriever",
WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
LoadNew = CreateWindowEx(0, ws.lpszClassName, "Help Program",
WS_BORDER | WS_CAPTION | WS_CHILD,
120,
80,
500,
300,
hWnd, NULL, hInstance, NULL);
hMainIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));
structNID.cbSize = sizeof(NOTIFYICONDATA);
structNID.hWnd = (HWND) hWnd;
structNID.uID = IDI_TRAYICON;
structNID.uFlags = NIF_ICON | NIF_MESSAGE;
structNID.hIcon = hMainIcon;
structNID.uCallbackMessage = WM_USER_SHELLICON;
Shell_NotifyIcon(NIM_ADD, &structNID);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
long FAR PASCAL WndProcParent(HWND hwnd,UINT message,UINT wParam,long lParam)
{
HDC hdc = NULL;
POINT lpClickPoint;
char buff[100] = "";
switch(message){
case WM_CREATE:
Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Close",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 680,480, 80, 30, hwnd, (HMENU)ID_CLOSE,
GetModuleHandle(NULL), NULL);
Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Help",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 680,450, 80, 30, hwnd, (HMENU)ID_HELPDAW,
GetModuleHandle(NULL), NULL);
break;
/*case WM_DESTROY:
PostQuitMessage(0);
return 0;*/
case WM_USER_SHELLICON:
switch(LOWORD(lParam))
{
case WM_LBUTTONDBLCLK:
ShowWindow(hwnd, SW_RESTORE);
break;
case WM_RBUTTONDOWN:
//get mouse cursor position x and y as lParam has the message itself
GetCursorPos(&lpClickPoint);
//place the window/menu there if needed
hPopMenu = CreatePopupMenu();
InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_OPEN,"&Open");
InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_HELPDAW,"&Help");
InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_CLOSE,"&Exit");
//workaround for microsoft bug, to hide menu w/o selecting
SetForegroundWindow(hWnd);
TrackPopupMenu(hPopMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_BOTTOMALIGN,lpClickPoint.x, lpClickPoint.y,0,hWnd,NULL);
SendMessage(hWnd,WM_NULL,0,0);
//MessageBox(NULL,"TEST rightclick","Testing ...",MB_OK);
return TRUE;
}
break;
case WM_COMMAND:
if(ID_CLOSE == LOWORD(wParam))
{
int iRes = MessageBox(NULL,"Do you want to Exit","Data Retriever",MB_YESNO|MB_ICONQUESTION);
if(IDYES == iRes)
{
Shell_NotifyIcon(NIM_DELETE,&structNID);
DestroyWindow(hWnd);
PostQuitMessage(0);
}
}
else if(ID_HELPDAW == LOWORD(wParam))
{
ShowWindow(LoadNew, SW_SHOW);
//MessageBox(NULL, "Help","Data Retriever",MB_OK|MB_ICONQUESTION);
}
else if(ID_OPEN == LOWORD(wParam))
{
ShowWindow(hWnd, SW_NORMAL);
}
break;
case WM_CLOSE:
Shell_NotifyIcon(NIM_DELETE,&structNID);
DestroyWindow(hWnd);
PostQuitMessage(0);
break;
case WM_SYSCOMMAND:
if(SC_MINIMIZE == wParam)
{
ShowWindow(hWnd,SW_HIDE);
return TRUE;
}
break;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
long FAR PASCAL WndProcChild(HWND hwnd,UINT message,UINT wParam,long lParam){
HDC hdc = NULL;
PAINTSTRUCT ps;
char buff[100] = "";
switch(message){
case WM_CREATE:
Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Unload",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20,20, 80, 30, hwnd, (HMENU)ID_MESSAGE,
GetModuleHandle(NULL), NULL);
break;
case WM_COMMAND:
if(ID_RETURN == LOWORD(wParam))
{
ShowWindow(hWnd, SW_SHOW);
ShowWindow(LoadNew,SW_HIDE);
//MessageBox(NULL, "Help","Data Retriever",MB_OK|MB_ICONQUESTION);
}
case WM_CLOSE:
ShowWindow(hWnd, SW_SHOW);
ShowWindow(LoadNew,SW_HIDE);
break;
case WM_PAINT:
RECT rect;
GetClientRect(LoadNew,&rect);
hdc = BeginPaint(LoadNew,&ps);
strcpy_s(buff,"TOP");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_TOP);
strcpy_s(buff,"RIGHT");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
strcpy_s(buff,"BOTTOM");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_BOTTOM);
strcpy_s(buff,"LEFT");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
strcpy_s(buff,"CENTER");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
strcpy_s(buff,"BOTTOM-LEFT");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_BOTTOM|DT_LEFT);
strcpy_s(buff,"BOTTOM-RIGHT");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_BOTTOM|DT_RIGHT);
strcpy_s(buff,"TOP-LEFT");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_TOP|DT_LEFT);
strcpy_s(buff,"TOP-RIGHT");
DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_TOP|DT_RIGHT);
EndPaint(LoadNew,&ps);
break;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
回答:
您的修改后的代码仍然对两个窗口使用相同的WndProc。您尝试使用相同的类名称调用RegisterClass两次。在更改名称之前,WndProcs不会分开。
ws.lpszClassName = "Data Retriever CHILD";
这个问题会更容易理解,如果你选中了来自的RegisterClass返回值 - 目前,第二个呼叫失败。这个代码还有其他问题(例如,子WndProc中的MessageBox调用真的很令人讨厌),但是这种改变应该足以让你着正确的方向前进。
回答:
你必须为每个窗口相同的WndProc代码。对于WM_CLOSE,您使用DestroyWindow(hWnd),其中hWnd是存储主窗口的全局变量。
因此,关闭你的子窗口会关闭主窗口,因为你告诉它。
以上是 C++中的子窗口问题 的全部内容, 来源链接: utcz.com/qa/258263.html