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

回到顶部