I'm having a problem in my program whenever I close the child window, the main window also exits.
I am a newbie in this programming.
The Correct Code:
/**
@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);
}
Your modified code is still using the same WndProc for both windows. You tried to call RegisterClass twice with the same class name. The WndProcs will not be separated until you change the name.
This problem would have been more readily apparent if you had checked the return value from RegisterClass - currently, the second call fails. There's other problems with this code (the MessageBox call in the child WndProc is really obnoxious, for example), but this change should be enough to get you headed in the right direction.