I was actually following a tutorial. I really want to get an answer because I will need to add icons to the window down the line. Getting images to show in the window would be the first step.
Sorry for some reason the update I added did not go through before. My solution is geared towards Unicode.
The corrected updated file is below :
#include <windows.h>
#include <commctrl.h>
using namespace std;
LPCWSTR szClassName = L"myWindowClass";
HWND hLogo;
HBITMAP hLogoImage;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void loadPictures();
void parentControls(HWND);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int icmdshow)
{
HWND hWnd;
WNDCLASSW wc = { 0 };
wc.style = 0;
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.lpfnWndProc = WndProc;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance = hInstance;
wc.hIcon = LoadIconW(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
if (!RegisterClassW(&wc))
{
const wchar_t Error01[] = L"Register Issue To Check On : "; /// Notice this
const wchar_t Error01_Caption[] = L"Error 01";
MessageBoxW(NULL, Error01, Error01_Caption, MB_OK | MB_ICONERROR);
return 0;
}
LPCWSTR parentWinTitle = L"My Window";
hWnd = CreateWindowW(szClassName, parentWinTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 250, 200, NULL, NULL, NULL, NULL);
if (hWnd == NULL)
{
const wchar_t Error02[] = L"Window Creation Issue To Check On : ";
const wchar_t Error02_Caption[] = L"Window Creation Issue To Check On : ";
MessageBoxW(NULL, Error02, Error02_Caption, MB_OK | MB_ICONERROR);
}
ShowWindow(hWnd, icmdshow);
UpdateWindow(hWnd);
MSG msg = { 0 };
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
loadPictures(); /// Must be called first, Calling the Images function in Create
parentControls(hWnd);
break;
/* case WM_COMMAND:
switch (wParam)
{
}
break;
*/
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, message, wParam, lParam);
}
return 0;
}
void parentControls(HWND hWnd)
{
hLogo = CreateWindowW(WC_STATICW, NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 70, 25, 100, 100, hWnd, NULL, NULL, NULL);
SendMessageW(hLogo, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hLogoImage);
}
void loadPictures()
{ /// bmp image save in file with main.cpp
LPCWSTR myBmp = L"bitmap1.bmp";
hLogoImage = (HBITMAP)LoadImageW(NULL, myBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}
case WM_COMMAND:
switch(wp)
{
}
break;
parentControls(hWnd); <--- never gets here
loadPictures(); /// Calling the Images function in Create
break;
parentControls and loadPictures are never reached in this switch statement.
loadPictures should be called first.
Remove the two lines, put them in WM_CREATE as follows:
case WM_CREATE:
loadPictures(); /// Calling the Images function in Create
parentControls(hWnd);
break;
Someone told me the answer should be here instead of updated above. I am sure I will be made aware that it is wrong if I add it here. I figure that is why the updates didn't take when I tried them before in the original post above. Either way the update/Answer is below.
#include <windows.h>
#include <commctrl.h>
using namespace std;
LPCWSTR szClassName = L"myWindowClass";
HWND hLogo;
HBITMAP hLogoImage;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void loadPictures();
void parentControls(HWND);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int icmdshow)
{
HWND hWnd;
WNDCLASSW wc = { 0 };
wc.style = 0;
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.lpfnWndProc = WndProc;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance = hInstance;
wc.hIcon = LoadIconW(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
if (!RegisterClassW(&wc))
{
const wchar_t Error01[] = L"Register Issue To Check On : "; /// Notice this
const wchar_t Error01_Caption[] = L"Error 01";
MessageBoxW(NULL, Error01, Error01_Caption, MB_OK | MB_ICONERROR);
return 0;
}
LPCWSTR parentWinTitle = L"My Window";
hWnd = CreateWindowW(szClassName, parentWinTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 250, 200, NULL, NULL, NULL, NULL);
if (hWnd == NULL)
{
const wchar_t Error02[] = L"Window Creation Issue To Check On : ";
const wchar_t Error02_Caption[] = L"Window Creation Issue To Check On : ";
MessageBoxW(0, Error02, Error02_Caption, MB_OK | MB_ICONERROR);
}
ShowWindow(hWnd, icmdshow);
UpdateWindow(hWnd);
MSG msg = { 0 };
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
loadPictures(); /// Must be called first, Calling the Images function in Create
parentControls(hWnd);
break;
/* case WM_COMMAND:
switch (wParam)
{
}
break;
*/
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, message, wParam, lParam);
}
return 0;
}
void parentControls(HWND hWnd)
{
hLogo = CreateWindowW(WC_STATICW, NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 70, 25, 100, 100, hWnd, NULL, NULL, NULL);
SendMessageW(hLogo, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hLogoImage);
}
void loadPictures()
{ /// bmp image save in file with main.cpp
LPCWSTR myBmp = L"bitmap1.bmp";
hLogoImage = (HBITMAP)LoadImageW(NULL, myBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}
Related
Im trying to create a windows application with winapi. So i want to have one parent window and one child window in it. Here is my code:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
const char szChildName[] = "Child window title";
const UINT PM_COLORCHANGED = WM_APP + 1;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASS wc;
char szAppName[] = "title";
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = (LPCWSTR)szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.hIcon = NULL;
wc.lpfnWndProc = ChildProc;
wc.lpszClassName = (LPCWSTR)szChildName;
RegisterClass(&wc);
hWnd = CreateWindow((LPCWSTR)szAppName,
(LPCWSTR)szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, iCmdShow);
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 hChild;
static RECT rect;
switch (message)
{
case WM_CREATE:
{
GetClientRect(hWnd, &rect);
hChild = CreateWindow((LPCWSTR)szChildName,
NULL,
WS_CHILD | WS_VISIBLE | WS_DLGFRAME,
5,
rect.bottom - 35,
rect.right - 10,
30,
hWnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL);
return 0;
}
case WM_SIZE:
{
return 0;
}
case PM_COLORCHANGED:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
return 0;
}
case WM_LBUTTONDOWN:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
This works perfect, so i see the child window at the bottom of the application.
But, instead of WNDCLASS I want to use WNDCLASSEX, which forces me to use RegisterClassEx() to register the windows. Also I want to use CreateWindowEx, my code looks like that:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
const char szChildName[] = "Child name";
const UINT PM_COLORCHANGED = WM_APP + 1;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASSEX wc;
char szAppName[] = "The Child Window";
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbClsExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hInstance = hInstance;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.lpszClassName = (LPCWSTR)szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wc);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.hIcon = NULL;
wc.lpfnWndProc = (WNDPROC)ChildProc;
wc.lpszClassName = (LPCWSTR)szChildName;
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
wc.lpszClassName,
L"parent window",
(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU),
200,
150,
1000,
1000,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, iCmdShow);
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 hChild;
static RECT rect;
switch (message)
{
case WM_CREATE:
{
GetClientRect(hWnd, &rect);
hChild = CreateWindowEx(NULL,
(LPCWSTR)szChildName,
L"child window",
(WS_CHILD | WS_VISIBLE | WS_DLGFRAME),
200,
150,
200,
200,
hWnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
return 0;
}
case WM_SIZE:
{
return 0;
}
case PM_COLORCHANGED:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
return 0;
}
case WM_LBUTTONDOWN:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
The problem: Now i only see the color of the child window, so the whole application has this background color of the child window, so somehow the pc repainted everything in the color of the child window. (no child window is even visible, everything i see is only this LTGRAY_Brush of the child window.
Weird is: If i delete the line where the child window is created, so this line:
hChild = CreateWindowEx(NULL,
(LPCWSTR)szChildName,
L"child window",
(WS_CHILD | WS_VISIBLE | WS_DLGFRAME),
200,
150,
200,
200,
hWnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
then even now, the background color gets the same as the one that i registered the child class with. Altough the child class hasn't been created. Thanks for your help.
Having such a simple Win32 app:
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
const wchar_t g_szClassName[] = L"Skeleton";
const wchar_t g_szChildClassName[] = L"Child";
wchar_t msgbuf[100];
void Example_DrawImage9(HDC hdc) {
Graphics graphics(hdc);
Image image(L"C:/Users/Darek/Fallout2_older/data/art/iface/armor_info.bmp");
graphics.DrawImage(&image, 0, 0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_PAINT:
swprintf_s(msgbuf, _T("WM_PAINT - PARENT - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProcChild(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_PAINT:
swprintf_s(msgbuf, _T("WM_PAINT - CHILD - hwnd: %02X\n"), (int)hwnd);
OutputDebugString(msgbuf);
return 0;
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;
ULONG_PTR token;
GdiplusStartupInput input = { 0 };
input.GdiplusVersion = 1;
GdiplusStartup(&token, &input, NULL);
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
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, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(0, g_szClassName, L"Skeleton", WS_POPUP | WS_BORDER, 0, 0, 190, 110, 0, 0, hInstance, 0);
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwnd, 0, 128, LWA_ALPHA);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// ---------------
HWND hwnd_child;
wc.lpfnWndProc = WndProcChild; // 1
wc.lpszClassName = g_szChildClassName;
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd_child = CreateWindowEx(0, g_szClassName, L"Child", /*WS_POPUP |*/ WS_BORDER, 200, 0, 190, 110, hwnd, 0, hInstance, 0);
swprintf_s(msgbuf, _T("hwnd_child: %02X\n"), (int)hwnd_child);
OutputDebugString(msgbuf);
SetWindowLong(hwnd_child, GWL_EXSTYLE, GetWindowLong(hwnd_child, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hwnd_child, 0, 128, LWA_ALPHA);
ShowWindow(hwnd_child, nCmdShow);
UpdateWindow(hwnd_child);
// ---------------
while (GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
GdiplusShutdown(token);
return Msg.wParam;
}
I've expected that the child window will run it's own WndProcChild window procedure but I get:
WM_PAINT - PARENT - hwnd: C0996
hwnd_child: C0998
WM_PAINT - PARENT - hwnd: C0998
what implies that the child window runs parent's procedure (WndProc) even if I've clearly assigned (line #1) a separate procedure for it.
I'm learning about creating a Windows desktop application using Visual C++.
I am creating a simple window that does nothing, and when I press the close button, I wanted to display a message box to confirm that I really want to close it before I close the window.
So I tried to do this using the Messagebox function when I got the WM_CLOSE message, but for some reason the program froze and wouldn't close.
I'm sorry, but can someone help me out?
The source is as follows. Thank you for your help.
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
TCHAR szClassName[] = TEXT("winapp");
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) {
MSG msg;
BOOL bRet;
if(!InitApp(hCurInst))
return FALSE;
if (!InitInstance(hCurInst, nCmdShow))
return FALSE;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (bRet == -1) {
MessageBox(NULL, TEXT("GetMessageエラー"), TEXT("Error"), MB_OK);
break;
}
else {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
return (int)msg.wParam;
}
ATOM InitApp(HINSTANCE hInst) {
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
return (RegisterClassEx(&wc));
}
BOOL InitInstance(HINSTANCE hInst, int nCmdShow) {
HWND hWnd;
hWnd = CreateWindow(
szClassName,
TEXT("Winapp"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
int id;
switch (msg){
case WM_CLOSE:
id = MessageBox(hWnd,TEXT("終了してもよろしいですか?"),TEXT("終了確認"),MB_YESNO | MB_ICONQUESTION);
if(id==IDYES){
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}
Try explicit use of unicode in your program. for exsmple using MessageBoxW instead of MessageBox and L"終了してもよろしいですか?" instead of TEXT("終了してもよろしいですか?") and change your windowproc a bit:
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
TCHAR szClassName[] = TEXT("winapp");
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) {
MSG msg;
BOOL bRet;
if(!InitApp(hCurInst))
return FALSE;
if (!InitInstance(hCurInst, nCmdShow))
return FALSE;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (bRet == -1) {
MessageBoxW(NULL, L"GetMessageエラー", L"Error", MB_OK);
break;
}
else {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
return (int)msg.wParam;
}
ATOM InitApp(HINSTANCE hInst) {
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
return (RegisterClassEx(&wc));
}
BOOL InitInstance(HINSTANCE hInst, int nCmdShow) {
HWND hWnd;
hWnd = CreateWindow(
szClassName,
TEXT("Winapp"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
int id;
switch (msg){
case WM_CLOSE:
id = MessageBoxW(hWnd,L"終了してもよろしいですか?", L"終了確認",MB_YESNO | MB_ICONQUESTION);
if(id==IDYES){
DestroyWindow(hWnd);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return (DefWindowProc(hWnd, msg, wp, lp));
}
If you try to press the close button, but the MessageBox does not pop up. Try to press the ALT key to see if it pops up. I suggest you handle the WM_PAINT message to ensure that the drawing message is processed.
Code:
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
TCHAR szClassName[] = TEXT("winapp");
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) {
MSG msg;
BOOL bRet;
if (!InitApp(hCurInst))
return FALSE;
if (!InitInstance(hCurInst, nCmdShow))
return FALSE;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (bRet == -1) {
MessageBox(NULL, TEXT("GetMessageエラー"), TEXT("Error"), MB_OK);
break;
}
else {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
return (int)msg.wParam;
}
ATOM InitApp(HINSTANCE hInst) {
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
return (RegisterClassEx(&wc));
}
BOOL InitInstance(HINSTANCE hInst, int nCmdShow) {
HWND hWnd;
hWnd = CreateWindow(
szClassName,
TEXT("Winapp"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
int id;
PAINTSTRUCT ps;
switch (msg) {
case WM_PAINT:
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_CLOSE:
id = MessageBox(hWnd, TEXT("終了してもよろしいですか?"), TEXT("終了確認"), MB_YESNO | MB_ICONQUESTION);
if (id == IDYES) {
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}
More reference:Why would a message box be not displaying?
I am trying to append text into a child window. After a lot of text is written, nothing else is appended. I have tried catching errors and walking through the debugger when text stops being appended, but nothing is out of the ordinary - the debugger walks through the code and no text will be added, along with no errors showing.
Here is my appending function:
void AppendText(HWND hEditWnd, std::string Text) {
int idx = GetWindowTextLength(hEditWnd);
SetLastError(NOERROR);
SendMessage(hEditWnd, WM_SETFOCUS, (WPARAM)hEditWnd, 0);
SendMessage(hEditWnd, EM_SETSEL, (WPARAM) idx, (LPARAM) idx);
SendMessage(hEditWnd, EM_REPLACESEL, WPARAM(TRUE), (LPARAM) ((LPSTR) Text.c_str()));
ULONG dwErrorCode = GetLastError();
if (dwErrorCode != NOERROR)
{
printf("fail with %u error\n", dwErrorCode);
}
}
Here is some sample code to try it out. In order to delay the function calls, I put a for loop for the program to crunch on. After ~30 seconds, text will stop being appended to the window.
#include <windows.h>
#include <tchar.h>
#include <string>
#include <windowsx.h>
#define ID_GO 1
#define ID_GO_ONCE 2
const char g_szClassName[] = "myWindowClass";
HWND hOut;
void AppendText(HWND hEditWnd, std::string Text) {
int idx = GetWindowTextLength(hEditWnd);
SetLastError(NOERROR);
SendMessage(hEditWnd, WM_SETFOCUS, (WPARAM)hEditWnd, 0);
SendMessage(hEditWnd, EM_SETSEL, (WPARAM) idx, (LPARAM) idx);
SendMessage(hEditWnd, EM_REPLACESEL, WPARAM(TRUE), (LPARAM) ((LPSTR) Text.c_str()));
ULONG dwErrorCode = GetLastError();
if (dwErrorCode != NOERROR)
{
printf("fail with %u error\n", dwErrorCode);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
HMENU hMenu, hSubMenu;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_GO_ONCE, "&Go Once");
AppendMenu(hSubMenu, MF_STRING, ID_GO, "&Go");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Output");
SetMenu(hwnd, hMenu);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_GO_ONCE:
AppendText(hOut, "-----HELLO-----\r\n");
AppendText(hOut, "-----TEST-----\r\n");
break;
case ID_GO:
while(1) {
AppendText(hOut, "-----HELLO-----\r\n");
for(int q = 0; q < 7000000; q++);
AppendText(hOut, "-----TEST-----\r\n");
for(int q = 0; q < 7000000; q++);
}
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;
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;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Test GUI",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 680, 402,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hOut = CreateWindowW(L"Edit", L"", WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE |
ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, 680 - 20, 340, hwnd, NULL, NULL, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Is there a limit on how much text can be displayed on a window?
I can only assume most of this works because I can't get past the CreateWindowEx check.
If someone would double check all of my fun button code that would be great too.
#include <windows.h>
#include <tchar.h> //I was told I needed this line but I don't believe I do.
#define ID_BTNENCRYPT 0
const char g_szClassName[] = "MyWindowClass";
HWND button;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) { //Fun button stuff
case WM_CREATE: {
button = CreateWindow("button",
"Encrypt Message",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
450, 620, 200, 30,
hwnd, (HMENU) ID_BTNENCRYPT, GetModuleHandle(NULL), NULL);
break;
}
case WM_COMMAND: { //More fun button stuff
switch (LOWORD(wParam)){
case ID_BTNENCRYPT: {
::MessageBox(hwnd, "This will be your message once I get my $h!t together", "Encrypted Message", MB_OK);
}
}
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
FreeConsole();
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_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
if (!RegisterClassEx(&wc)) {
::MessageBox(NULL, "Window Registration Status: Hopelessly F***ed", "", MB_OK);
return 0;
} //No apparent error in Window Registration
Here's where I need help
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Great Window",
WS_OVERLAPPEDWINDOW,
300, 300,
350, 350,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
::MessageBox(NULL,"Window Creation Status: Gone to $h!t", "", MB_OK);
}
I unfortunately get the error message that yes, my window creation has failed.
ShowWindow(hwnd, nCmdShow); //Just the end of my code from here on out.
UpdateWindow(hwnd); //Hopefully there aren't any fatal errors.
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Your WndProc() is not returning the return value of DefWindowProc() for unhandled messages. There is a missing return statement, so you end up falling to return 0 for all messages. When WM_NCCREATE returns 0, CreateWindowEx() fails:
If an application processes this message, it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle.
You need to change this:
default:
DefWindowProc(hwnd, msg, wParam, lParam);
To this:
default:
return DefWindowProc(hwnd, msg, wParam, lParam);