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.
Related
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;
I am creating a Windows desktop application using win32 api in visual studio 2019. I know there are many other options avialable to build UI like MFC, XAMAL and C#, but i needed to build it in win32. I have learnt some basics in win32 api but recently i was working on tabControll and there i got an issue or i missed some thing. I am creating two tabs and want to add different content withing them. My current code is working and creating the tabs but it is adding same content in both tabs. How should i define each tab's content differently.
void createTabView(HWND hWnd) {
RECT rcClient;
INITCOMMONCONTROLSEX icex;
static HWND hwndTab_1_1_1;
HWND hwndTab;
TCITEM tie;
int i;
TCHAR achTemp[256];
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
GetClientRect(hWnd, &rcClient);
hwndTab = CreateWindow(WC_TABCONTROL, L"",
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
0, 0, rcClient.right, rcClient.bottom,
hWnd, NULL, hInst, NULL);
// Add tabs for each day of the week.
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
tie.pszText = tabLBL1;
TabCtrl_InsertItem(hwndTab, 1, &tie);
tie.pszText = tabLBL2;
TabCtrl_InsertItem(hwndTab, 2, &tie);
SendMessage(hwndTab, WM_SETFONT,
reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
HWND hwndStatic = CreateWindow(WC_STATIC, L"",
WS_CHILD | WS_VISIBLE | WS_BORDER,
200, 200, 100, 100, // Position and dimensions; example only.
hwndTab, NULL, hInst, // g_hInst is the global instance handle
NULL);}
The tab control triggers the WM_NOTIFY signal when the tab page is switched, so as long as we process the WM_NOTIFY message, we can control the tab control message.
In the WM_NOTIFY message:
wParam: a control ID that identifies the WM_NOTIFY message sent.
lParam: a pointer to the NMHDR structure.
Therefore, we can determine the notification code sent by the Tab control in the WM_NOTIFY message processing program by judging the code value in the NMHDR structure.
We can use TCN_SELCHANGE to handle the operation when the Tab tab changes, and use TabCtrl_GetCurSel to get the index of the current tab and define the content of the current tab.
Here is the sample:
#include <Windows.h>
#include <commctrl.h>
LRESULT CALLBACK WndProc(HWND, UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("windows");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
}
hwnd = CreateWindow(szAppName,
TEXT("the hello program"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
while (GetMessageW(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
static HINSTANCE hInstance;
static HWND hwndTab = 0 , hwndStatic = 0;
TCITEM tie;
RECT rcClient;
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
TCHAR tabLBL1[256];
GetClientRect(hwnd, &rcClient);
switch (message)
{
case WM_CREATE:
{
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
hwndTab = CreateWindow(WC_TABCONTROL, "",
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
0, 0, rcClient.right, rcClient.bottom,
hwnd, NULL, hInstance, NULL);
// Add tabs for each day of the week.
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
wsprintf(tabLBL1, "tab1");
tie.pszText = tabLBL1;
TabCtrl_InsertItem(hwndTab, 0, &tie);
wsprintf(tabLBL1, "tab2");
TabCtrl_InsertItem(hwndTab, 1, &tie);
SendMessage(hwndTab, WM_SETFONT,
reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
hwndStatic = CreateWindow(WC_STATIC, "",
WS_CHILD | WS_VISIBLE | WS_BORDER,
200, 200, 100, 100, // Position and dimensions; example only.
hwndTab, NULL, hInstance, // g_hInst is the global instance handle
NULL);
ShowWindow(hwndStatic,TRUE);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_NOTIFY:
if (((LPNMHDR)lParam)->code == TCN_SELCHANGE)
{
int tabID = TabCtrl_GetCurSel(hwndTab);
switch (tabID)
{
case 0:
ShowWindow(hwndStatic, TRUE);
break;
case 1:
ShowWindow(hwndStatic, FALSE);
break;
default:
break;
}
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
Not sure if this is the solution, but the iItem parameter to TabCtrl_InsertItem is zero-based. Try:
tie.pszText = tabLBL1;
TabCtrl_InsertItem(hwndTab, 0, &tie);
tie.pszText = tabLBL2;
TabCtrl_InsertItem(hwndTab, 1, &tie);
Also (and I'm not sure if this is relevant), you look like you intended to call InitCommonControlsEx in your code but fail to do so.
I want to change button colors when the user click on it.
The main plan is: every month 10th one worker's button go to red and if the worker done his job then click on the button and it going to be green.
I have no idea what to do.
I already have this code. I just created a window and add a button to it:
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
AddButton(hWnd);
break;
default:
return DefWindowProcW(hWnd, msg, wp, lp);
}
}
void AddButton(HWND hWnd)
{
CreateWindowW(L"Button", L"Change colors", WS_VISIBLE | WS_CHILD,
350, 200,
100, 100,
hWnd,
NULL,
NULL,
NULL);
}
So I tried WM_LBUTTONDOWN. I think this is something when the user click on the button the program will do something. I put in the switch(msg) case WM_LBUTTONDOWN:.
But no idea what's next.
Here is a simple demo to show how to detect click on a button, and change the color of button when you click on it.
#pragma comment(linker, "/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' \
publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment(lib, "comctl32.lib")
#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
static BOOL flag = false;
ATOM RegisterWndClass(HINSTANCE hInst);
BOOL CreateMainWnd(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hInst;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hInstPrev, LPWSTR lpszCmdLine,
int nCmdShow)
{
INITCOMMONCONTROLSEX icex = { 0 };
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_USEREX_CLASSES | ICC_BAR_CLASSES |
ICC_COOL_CLASSES | ICC_TAB_CLASSES | ICC_WIN95_CLASSES |
ICC_PROGRESS_CLASS | ICC_PAGESCROLLER_CLASS;
InitCommonControlsEx(&icex);
MSG msg;
hInst = hInstance;
if (!RegisterWndClass(hInstance))
return NULL;
if (!CreateMainWnd(hInstance, nCmdShow))
return NULL;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
};
ATOM RegisterWndClass(HINSTANCE hInstance)
{
WNDCLASS wndClass = { 0 };
wndClass.style = CS_DBLCLKS;
wndClass.lpfnWndProc = MainWndProc;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = L"MainClass";
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
return RegisterClass(&wndClass);
}
BOOL CreateMainWnd(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = CreateWindow(L"MainClass", L"Buttons sample",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
GetSystemMetrics(SM_CXSCREEN) / 2 - 115,
GetSystemMetrics(SM_CYSCREEN) / 2 - 50,
230, 100, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
HBITMAP hBitmap = NULL;
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
// Owner draw button
CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON |
BS_OWNERDRAW, 10, 10, 60, 30, hWnd,
(HMENU)10001, hInst, NULL);
// Custom draw button
CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 80,
10, 60, 30, hWnd, (HMENU)10002, hInst, NULL);
// Bitmap button
HWND hBitmapButton = CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE
| BS_PUSHBUTTON | BS_BITMAP,
150, 10, 60, 30, hWnd,
(HMENU)10003, hInst, NULL);
HDC hDC = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hDC);
hBitmap = CreateCompatibleBitmap(hDC, 55, 25);
SelectObject(hMemDC, hBitmap);
SetDCBrushColor(hMemDC, RGB(0, 0, 255));
RECT r = { 0 };
r.left = 0;
r.right = 55;
r.top = 0;
r.bottom = 25;
FillRect(hMemDC, &r, (HBRUSH)GetStockObject(DC_BRUSH));
DeleteDC(hMemDC);
ReleaseDC(hWnd, hDC);
SendMessage(hBitmapButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP,
(LPARAM)hBitmap);
return 0;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 10001:
MessageBox(hWnd, L"Owner draw button clicked", L"Message", NULL);
return 0;
case 10002:
MessageBox(hWnd, L"Custom draw button clicked", L"Message", NULL);
return 0;
case 10003:
MessageBox(hWnd, L"Bitmap button clicked", L"Message", NULL);
return 0;
}
break;
// Owner draw button
case WM_DRAWITEM:
if (wParam == 10001)
{
if (flag == false)
{
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
SetDCBrushColor(lpDIS->hDC, RGB(255, 0, 0));
SelectObject(lpDIS->hDC, GetStockObject(DC_BRUSH));
RoundRect(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
lpDIS->rcItem.right, lpDIS->rcItem.bottom, 5, 5);
}
else
{
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
SetDCBrushColor(lpDIS->hDC, RGB(0, 255, 0));
SelectObject(lpDIS->hDC, GetStockObject(DC_BRUSH));
RoundRect(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
lpDIS->rcItem.right, lpDIS->rcItem.bottom, 5, 5);
}
flag = !flag;
return TRUE;
}
break;
// Custom draw button
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case NM_CUSTOMDRAW:
if (((LPNMHDR)lParam)->idFrom == 10002)
{
LPNMCUSTOMDRAW lpnmCD = (LPNMCUSTOMDRAW)lParam;
switch (lpnmCD->dwDrawStage)
{
case CDDS_PREPAINT:
SetDCBrushColor(lpnmCD->hdc, RGB(0, 255, 0));
SetDCPenColor(lpnmCD->hdc, RGB(0, 255, 0));
SelectObject(lpnmCD->hdc, GetStockObject(DC_BRUSH));
SelectObject(lpnmCD->hdc, GetStockObject(DC_PEN));
RoundRect(lpnmCD->hdc, lpnmCD->rc.left + 3,
lpnmCD->rc.top + 3,
lpnmCD->rc.right - 3,
lpnmCD->rc.bottom - 3, 5, 5);
return TRUE;
}
}
break;
}
break;
case WM_DESTROY:
if (hBitmap != NULL)
DeleteObject((HBITMAP)hBitmap);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
Try to make some modifications to "if" conditions to meet your needs.
Alright so this code is pretty long over a short problem so I will kinda use <--- arrows to point it out for you, but down in my switch case WM_COMMAND:
I am kinda confused on using the return 0/ break.
return 0; seems to jump me outside of the whole WndProc function (skips over some code)
break; just breaks out of the switch statement but continues.
So does that mean I should use return 0; at the very end of my switch statement to prevent from moving on? Or is there something just wrong with my WM_MAXMININFO, because I never had that problem until after I changed the return 0 to break; The reason I ask is because once it hits WM_MAXMININFO I get a Access Violation. (That may be that cause of all of this).
// Win32Project2.cpp : Defines the entry point for the application.
#include "stdafx.h"
#include "Win32Project2.h"
#include <Windows.h>
#include <Windowsx.h>
#include <shellapi.h>
#include "ProcessFind.h"
#include <WinUser.h>
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#define BUTTON L"button"
#define szDefault L"Awaiting Commands..."
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdShow, int iCmdLine)
{
wchar_t szAppName[] = L"Game Launcher";
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndclass);
hwnd = CreateWindow(szAppName, L"GameLauncher v1.0", WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 375, 100, NULL, NULL, hInstance, 0);
ShowWindow(hwnd, iCmdLine);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
static HWND hUserBox;
static HWND hWindowButton;
HBITMAP hImage = (HBITMAP)LoadImage(NULL, L"?C:\\Users\\chaos\\Desktop\\Capture.PNG", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_LOADTRANSPARENT);
switch (message)
{
case WM_CREATE:
CreateWindowEx(NULL, BUTTON, L"Check for process", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX , 5, 35, 150, 25, hwnd, (HMENU)2, NULL, NULL);
CreateWindow(BUTTON, L"Minecraft", WS_CHILD | WS_VISIBLE, 250, 5, 100, 25, hwnd, (HMENU)1, NULL, NULL);
CreateWindow(BUTTON, L"Options", WS_CHILD | WS_VISIBLE | WS_DISABLED, 250, 30, 100, 25, hwnd, (HMENU)3, NULL, NULL);
hUserBox = CreateWindow(L"static", L"Awaiting Commands...", WS_CHILD | WS_VISIBLE | WS_BORDER, 5, 5, 240, 25, hwnd, (HMENU) 2, NULL, NULL);
return 0;
case WM_COMMAND:
switch (LOWORD(wparam))
{
case 1:
{
wchar_t* szProccessToKill = new wchar_t[20];
GetWindowText(hUserBox, szProccessToKill, 20);
// Checking checked status on checkbox. (Say that 5 times fast lol)
if (IsDlgButtonChecked(hwnd, 2) == BST_CHECKED)
{
ProcessFind testFunction;
SetWindowText(hUserBox, L"Ending process");
Sleep(1000);
testFunction.EndProcess(L"java.exe");
SetWindowText(hUserBox, L"Launching Minecraft...");
Sleep(1000);
ShellExecute(NULL, L"open", L"MinecraftLauncher", NULL, L"C:\\Program Files (x86)\\Minecraft", 6);
SetWindowText(hUserBox, L"Minecraft has launched sucessfully!");
Sleep(1000);
SetWindowText(hUserBox, szDefault);
}
else if (IsDlgButtonChecked(hwnd, 2) == BST_UNCHECKED)
{
SetWindowText(hUserBox, L"Launching Minecraft...");
HINSTANCE ErrorCode = ShellExecute(NULL, L"open", L"C:\\Program Files (x86)\\Minecraft\\MinecraftLauncher", NULL, NULL, 1);
int ErrorCodeInt = (int)ErrorCode;
switch (ErrorCodeInt)
{
case 0:
MessageBox(NULL, L"The operating system is out of memory or resources.", L"Error", MB_OK | MB_ICONERROR);
break;
case ERROR_FILE_NOT_FOUND:
MessageBox(NULL, L"The specified file was not found.", L"Error", MB_OK | MB_ICONERROR);
break;
case ERROR_PATH_NOT_FOUND:
MessageBox(NULL, L"The specified path was not found.", L"Error", MB_OK | MB_ICONERROR);
break;
default:
SetWindowText(hUserBox, L"Minecraft has launched successfully");
Sleep(1500);
break;
}
SetWindowText(hUserBox, szDefault);
}
delete[] szProccessToKill;
break; <--- **If this is not a return 0;**
}
case 3:
{
break;
}
default:
break;
}
//Set Min / Max Width/Height size.
case WM_GETMINMAXINFO: <-- It will jump down here and give me an access violation error:
{
MINMAXINFO* MMI = (MINMAXINFO*)lparam;
MMI->ptMaxTrackSize.x = 375;
MMI->ptMaxTrackSize.y = 100;
MMI->ptMinTrackSize.x = 375;
MMI->ptMinTrackSize.y = 100;
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
return 0;
}
I will kinda shorten it up straight to the problem for you guys:
SetWindowText(hUserBox, szDefault);
}
delete[] szProccessToKill;
break; <--- **If this is not a return 0;**
}
case 3:
{
break;
}
default:
break;
}
//Set Min / Max Width/Height size.
case WM_GETMINMAXINFO: <-- It will jump down here and give me an access violation error:
{
MINMAXINFO* MMI = (MINMAXINFO*)lparam;
MMI->ptMaxTrackSize.x = 375;
MMI->ptMaxTrackSize.y = 100;
MMI->ptMinTrackSize.x = 375;
MMI->ptMinTrackSize.y = 100;
return 0;
}
following code is not working .i am trying to get text from edit control but it does not work.m tired by trying all possible codes looking documentation on msdn etc...
case WM_COMMAND:
switch(LOWORD(wParam)){
case 1:
::MessageBox(hwnd,"button clicked","message",MB_OK);
break;
case 2:
TCHAR t[20]; //
GetWindowText(text_box,t,19);// this is not working????????????????
::MessageBox(hwnd,t,t,MB_OK);
cout<<t;
break;
for refrence below is the complete code :
#include <windows.h>
#include<iostream>
using namespace std;
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND text_field, button , text_box;
char text_saved[20];
switch(msg)
{ case WM_CREATE:
text_field = CreateWindow("STATIC",
"Hello World",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,20, 90,25,
hwnd,
NULL,NULL,NULL);
button = CreateWindow("BUTTON",
"push button",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,50, 100,20,
hwnd,
(HMENU)1,NULL,NULL
) ;
text_box = CreateWindow("EDIT",
" ",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,80, 200,25,
hwnd,
NULL,NULL,NULL
);
CreateWindow("BUTTON",
"Save",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,120, 100,20,
hwnd,
(HMENU)2,NULL,NULL
);
break;
case WM_COMMAND:
switch(LOWORD(wParam)){
case 1:
::MessageBox(hwnd,"button clicked","message",MB_OK);
break;
case 2:
TCHAR t[20];
GetWindowText(text_box,t,19);
::MessageBox(hwnd,t,t,MB_OK);
cout<<t;
break;
}
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;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500,500,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
You've defined text_box (and the other variables) as local to the WndProc function, meaning their values are lost every time that function is called to process a message. You need to move them outside of the function scope (or make them static) if you want to preserve their values from one message to the next.
This is a working reworked version of your code, replacing the local variable text_box (which doesn't retain information from one call to the next) with a numerical control id and use of GetDlgItem, changing from ANSI to Unicode text, and fixing some other stuff, while mainly keeping the formatting:
#undef UNICODE
#define UNICODE
#include <windows.h>
#include<iostream>
#include <string>
using namespace std;
namespace g {
const auto class_name = L"myWindowClass";
const auto push_button_id = 1;
const auto save_button_id = 2;
const auto edit_field_id = 3;
const auto h_instance = ::GetModuleHandle( nullptr );
} // namespace g
// Step 4: the Window Procedure
void create_controls( const HWND hwnd )
{
CreateWindow( L"STATIC",
L"Hello World",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,20, 90,25,
hwnd,
nullptr, g::h_instance, nullptr );
CreateWindow( L"BUTTON",
L"push button",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,50, 100,20,
hwnd,
(HMENU) g::push_button_id, g::h_instance, nullptr
) ;
CreateWindow( L"EDIT",
L"",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,80, 200,25,
hwnd,
(HMENU) g::edit_field_id, g::h_instance, nullptr
);
CreateWindow( L"BUTTON",
L"Save",
WS_VISIBLE | WS_CHILD | WS_BORDER,
20,120, 100,20,
hwnd,
(HMENU) g::save_button_id, g::h_instance, nullptr
);
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch(msg)
{
case WM_CREATE:
create_controls( hwnd );
break;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case 1:
::MessageBox( hwnd, L"button clicked", L"message", MB_SETFOREGROUND );
break;
case 2:
const HWND text_box = GetDlgItem( hwnd, g::edit_field_id );
const int n = GetWindowTextLength( text_box );
wstring text( n + 1, L'#' );
if( n > 0 )
{
GetWindowText( text_box, &text[0], text.length() );
}
text.resize( n );
::MessageBox(hwnd, text.c_str(), L"The text:", MB_SETFOREGROUND );
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int main()
{
//Step 1: Registering the Window Class
WNDCLASSEX wc = { sizeof( WNDCLASSEX ) };
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g::h_instance;
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
wc.lpszMenuName = nullptr;
wc.lpszClassName = g::class_name;
wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(nullptr, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_SETFOREGROUND );
return E_FAIL;
}
// Step 2: Creating the Window
const HWND hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g::class_name,
L"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500,500,
nullptr, nullptr, g::h_instance, nullptr);
if(hwnd == nullptr)
{
MessageBox(nullptr, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
return E_FAIL;
}
ShowWindow(hwnd, SW_SHOWDEFAULT); // Note: any other value is replaced.
UpdateWindow(hwnd); // Not strictly necessary.
// Step 3: The Message Loop
MSG Msg;
int get_message_result;
while( (get_message_result = GetMessage(&Msg, nullptr, 0, 0)) > 0 )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return (get_message_result < 0? E_FAIL : Msg.wParam);
}