I have been programming a Window Application, for Windows, and in Debug mode everything works but when I want switch to release mode the Window that opens in Debug does not open. If I try it without Visual Studio a Task is visible in Task manager but no window.
To be honest right now I can't understand anything I have in this code, I understood it 3 months ago but due to circumstances I have not worked with this in the last months and this is my first window application and my first application I release.
The following code should be everything that handles the creation of the Window.
This program creates a simple user interface (WinAPI) for entering the desired button cycles.
The entered button cycles are then sent to the button test device via a bound TCP / IP client.
As soon as the push button test device is finished with the switching cycles, it transmits the incorrect switching and the task switching to the TCP / IP client.
As soon as the data has been received by the TCP / IP client, it is written to a .csv file by a CSV writer.
*/
#include <Windows.h>
#include <cassert>
#include <wingdi.h>
#include "TCP-IP-Client.h"
HWND hWndEdit;
wchar_t buffer[1024];
LRESULT CALLBACK MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_COMMAND:
if (LOWORD(wParam) == 10) {
GetWindowText(hWndEdit, buffer, 1024);
int Input[1] = { _wtoi(buffer) };
switch (TcpIpClient(Input)) {
case 10:
MessageBox(hWnd, L"Can't start Winsock" , L"Benachrichtigung", MB_ICONERROR);
break;
case 11:
MessageBox(hWnd, L"Can't create socket", L"Benachrichtigung", MB_ICONERROR);
break;
case 12:
MessageBox(hWnd, L"Can't connect to server", L"Benachrichtigung", MB_ICONERROR);
break;
case 13:
MessageBox(hWnd, L"Socket Error!", L"Benachrichtigung", MB_ICONERROR);
break;
}
}
break;
case WM_CTLCOLOREDIT:
if (hWndEdit == (HWND)lParam) {
HDC hdc = (HDC)wParam;
SetBkColor(hdc, RGB(211, 211, 211));
//SetTextColor(hdc, RGB(211, 211, 211)); // For diffrent color of latters
SetDCBrushColor(hdc, RGB(211, 211, 211));
return (LRESULT)GetStockObject(DC_BRUSH);
}
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 20, 20, L"Gewünschte Taster Zyklen Eingeben", strlen("Gewünschte Taster Zyklen Eingeben"));
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
HWND hWnd;
HWND hButton;
WNDCLASS wc;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MessageHandler;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"WINAPITest";
assert(RegisterClass(&wc));
hWnd = CreateWindow(L"WINAPITest", L"WinAPI Tutorial", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, 0, 0, hInstance, 0);
hButton = CreateWindow(L"button", L"OK", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 40, 100, 200, 50, hWnd, (HMENU)10, hInstance, 0);
hWndEdit = CreateWindow(L"edit", NULL, WS_TABSTOP | WS_CHILD | WS_BORDER | WS_VISIBLE, 40, 48, 200, 50, hWnd, 0, 0, 0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (true) {
BOOL result = GetMessage(&msg, 0, 0, 0);
if (result > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
return result;
}
}
}
Two bugs:
As I called out in the comments, you are forgetting to invoke EndPaint and have a missing break statement. Fixing that and cleaning up your code so you don't have to duplicate the string:
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
const wchar_t* message = L"Gewünschte Taster Zyklen Eingeben";
TextOut(hdc, 20, 20, message, wcslen(message));
EndPaint(hWnd, &ps);
return 0; // THIS LINE ADDED
Bug #2 is that you are forgetting to invoke RegisterClass on your WNDCLASSEX structure. Also, it's usually a good idea to default initialize that struct (to zeros) in case you missed a field or wanted to skip it.
wc = {}; // zero-init THIS LINE ADDED
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MessageHandler;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"WINAPITest";
RegisterClass(&wc); // THIS LINE ADDED
After I removed the TCP Client stuff, I got your program to somewhat work:
And for some style points, I cleaned up this:
while (true) {
BOOL result = GetMessage(&msg, 0, 0, 0);
if (result > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
return result;
}
}
To simply be this:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
Related
I am very new to Win32 so please be gentle as I am surely not describing my question well at all, but am extremely serious about learning more. So, I have modified my main window to include the option to edit, both write and delete, text, but in order to feel comfortable moving forward, I need to know where exactly the main window knew to create the edit controls.
Are the edit controls creation part of the CreateWindowEx that creates the main window? Or are they only created when I click on the update region that then informs my WM_CREATE case to begin the second CreateWindowEx that actually includes the Edit Styles that enable the controls? This is the only way I can make the order of things make sense, but I need to make sure I'm not just jumping at the first "logical" conclusion. Is my theory correct or completely wrong?
#include <Windows.h>
#include "resource.h"
LPCWSTR g_szClassName{ L"My Window Class" };
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
{
HFONT hfDefault;
HWND hEdit;
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", L"",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL |
ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
0, 0, 100, 100,
hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
if (hEdit == NULL) {
MessageBox(hwnd, L"Could not create edit box.", L"Error!", MB_OK | MB_ICONERROR);
}
hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
break;
}
case WM_SIZE:
{
HWND hEdit;
RECT rcClient;
GetClientRect(hwnd, &rcClient);
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER);
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc.lpszClassName = g_szClassName;
wc.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"Windows registration failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
L"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
MessageBox(NULL, L"Windows registration failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Before CreateWindow/Ex() exits, it sends a WM_CREATE message (among several other mesages) to the window that is being created. CreateWindow/Ex() does not exit until all of those messages have been processed (unless an error occurs).
So, by the time CreateWindowEx() in your main() has exited, your main window has been fully created, including any child controls that its WM_CREATE handler creates.
I have a problem with using the % operator. This is hard to explain, so I'll just show my code first.
#include <windows.h>
const char ClassName[] = "WindowClass";
int divisible = 1;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 50, NULL);
break;
case WM_TIMER:
{
if (divisible % 15 == 0) {
MessageBox(hwnd, "a", "a", MB_ABORTRETRYIGNORE | MB_ICONASTERISK);
}
divisible++;
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_SHIELD);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
wc.hIconSm = LoadIcon(NULL, IDI_SHIELD);
RegisterClassEx(&wc);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
ClassName,
"Tank Survival",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 820, 642,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
So what happens is that the messagebox in WM_TIMER repeats every time WM_TIMER is called although it should only run every 15 times WM_TIMER is called.
Any help would be appreciated.
Thanks!
Well, some good points have been made in the comments, but the essential problem here is that Windows continues to dispatch messages (including WM_TIMER messages) while the message box is on the screen so you end up recursively calling MessageBox each time the timer fires (but, since these are all on top of one another, you only see the one).
One way to resolve this is to kill the timer while the message box is on the screen, like so:
case WM_TIMER:
{
if (divisible % 15 == 0) {
KillTimer (hwnd, 1);
MessageBox (hwnd, "a", "a", MB_ABORTRETRYIGNORE | MB_ICONASTERISK);
SetTimer (hwnd, 1, 50, NULL);
}
divisible++;
break;
}
But you should debug this before you change the code, so that you fully understand what's going on.
I just starting learning to program, and I just succeed making window.
I'm trying to make a STATIC text area, so I did like this.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
textfield = case WM_CREATE:
CreateWindow("STATIC", "Hggggg", WS_VISIBLE | WS_CHILD | WS_BORDER,
1, 1, 100, 20, hwnd, 0, 0, 0);
break;
I was watching a youtube video for beginners, and I followed the video. but somehow VisualStudio makes redcurvy-underline under "CreateWindow". I don't really know why.
Compiling fails, and shows error Number "C2065", "C2664".
This is my whole code
#include <Windows.h>
HWND windowHandle;
HWND textfield;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIconSm = 0;
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpszClassName = L"rerere";
wc.lpszMenuName = 0;
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
//
RegisterClassEx(&wc);
windowHandle = CreateWindowEx(WS_EX_ACCEPTFILES, L"rerere", L"rerere",
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX ) | WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN)-300)/2, (GetSystemMetrics(SM_CYSCREEN)-300)/2, 300, 300, 0, 0, hInstance, 0);
//
if (windowHandle == 0)
MessageBoxA(0, "creafjeiwa", "ERROR", 0);
//
ShowWindow(windowHandle, showCmd);
//
UpdateWindow(windowHandle);
//
MSG msg;
SecureZeroMemory(&msg, sizeof(MSG));
int returnValue = 0;
while ((returnValue = GetMessage(&msg, 0, 0, 0)) != 0)
{
if (returnValue == -1)
{
MessageBoxA(windowHandle, "getmessage fa", "ssss", 0);
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
textfield = CreateWindow("STATIC", "Hggggg", WS_VISIBLE | WS_CHILD | WS_BORDER, 1, 1, 100, 20, hwnd, 0, 0, 0);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
How can I make Static text area?
Your project is in Unicode, you must use Unicode text fields instead of ANSI
CreateWindow(L"STATIC", L"Hggggg", ...
All text fields need the L prefix. If using ANSI, then use ANSI version of API code. You have done that with MessageBoxA. But it's more efficient to use Unicode functions throughout with the L prefix for text.
I have tried this:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
case WM_MOVE:
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
}
case WM_CTLCOLORSTATIC:
{
HDC hdc = (HDC) wParam;
SetBkMode (hdc, TRANSPARENT);
return (LRESULT)(GetStockObject(NULL_BRUSH));
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int main()
{
WNDCLASSEX wc;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(GetStockObject(NULL_BRUSH));
wc.lpszMenuName = NULL;
wc.lpszClassName = L"MY CLASS";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
HWND hwnd = CreateWindowEx(0, L"MY CLASS", NULL, WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL);
HWND child = CreateWindowEx(0, L"STATIC", L"Text", WS_VISIBLE | WS_CHILD , 50, 50, 50, 50, hwnd, NULL, NULL, NULL);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
It creates window, which looks transparent, because it shows the same as on screen, however after moving window main window background stays the same. I want to ask, where the problem may be.
P.S. it is just test code, so, please, do not write advices not suited with my question.
Thanks.
EDIT: I want this because I'm going to make some helpers for users who don't know how to do some stuff. Result should be something like regular some program view with come spots marked, what means press here, when here, after that here and etc.
I think you start point should be with taking a look on Layered Windows
http://msdn.microsoft.com/en-us/library/ms997507.aspx
it is most common way for playing with custom shape and (semi)transparent windows.
UPD. There is also old API for making custom shaped windows:
int SetWindowRgn( HWND hWnd, HRGN hRgn, BOOL bRedraw );
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);
}
You have the same wndproc code for each window. For WM_CLOSE, you DestroyWindow(hWnd), where hWnd is the global that stores your main window.
So, closing your child window closes the main window because you told it to.
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.
ws.lpszClassName = "Data Retriever CHILD";
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.