Reputation: 11237
In a simple WINAPI program, I am making a dialog box (which I made with ResEdit).
However, the dialog box is not displaying and the DialogBox()
call is returning -1. GetLastError()
returned 1812 (The specified image file did not contain a resource section.)
main.cpp
/*default stuff, like including windows.h, etc... */
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
hInst = hThisInstance;
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/*default stuff, initializing fields of WNDCLASSEX struct */
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Hello World"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
0, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Creating controls ... */
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Default : message loop. It will run until GetMessage() returns 0 */
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
HMENU hMenu, hSubMenu;
HICON hIcon, hIconSm;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&File");
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABT, "&About");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&Help");
SetMenu(hwnd, hMenu);
hIcon = (HICON) LoadImage(NULL, "iconBIG.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
if (hIcon)
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
hIconSm = (HICON) LoadImage(NULL, "iconSMALL.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
if (hIconSm)
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSm);
break;
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_ACCEPTBTN:
/* handling the controls */
break;
case ID_FILE_EXIT:
/* handling more controls ... */
PostQuitMessage(0);
break;
case ID_HELP_ABT:
int ret = DialogBox(GetModuleHandle, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);
/*PROBLEM: DialogBox returns -1*/
if (ret == -1) {
DWORD dw = GetLastError(); // error 1812
char buffer[70];
sprintf(buffer, "Failed with %d", dw);
MessageBox(hwnd, buffer, "", MB_OK);
}
break;
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default: return FALSE;
}
}
resourceDialog.rc
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
LANGUAGE 0, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
GROUPBOX "Static", 0, 3, 7, 118, 82, 0, WS_EX_LEFT
LTEXT "hello,\nworld!", 0, 16, 21, 20, 17, SS_LEFT, WS_EX_LEFT
PUSHBUTTON "Cancel", IDCANCEL, 129, 24, 50, 14, 0, WS_EX_LEFT
DEFPUSHBUTTON "OK", IDOK, 129, 7, 50, 14, 0, WS_EX_LEFT
}
resource.h
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#define IDD_DIALOG1 100
/* Dont redefine IDOK and IDCANCEL */
/*#define IDOK 40000
#define IDCANCEL 40001*/
Why is the dialog box not displaying? I am following along winprog.org's tutorial and doing as they say.
Ide: Codeblocks Compiler: GCC
Upvotes: 0
Views: 138
Reputation: 13099
Gawd almighty! The amount of stuff I had to add back in (it was there in the first place, right?) was alarming. While I applaud your effort to keep the question brief, one needs to be very careful when posting a code snippet. The one you posted wouldn't compile and then when it did, there were still a great number of ommisions - by not posting your code verbatim, it's hard to know just what the issue was.
This is the contents of main.cpp
after editing. I still don't know what your problem was - you'll be able to compare this file to your own to deduce that for yourself, I hope. :)
You also probably need to remove the reference to an icon in the structure used for class registration, since you're setting it in WM_CREATE
/*
These are the steps I took.
1. Add this to the code:
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <windows.h>
#include <cstdio>
#include "resource.h"
HINSTANCE hInst;
TCHAR *szClassName = _T("mClassName");
#define ID_FILE_EXIT 40001
#define IDC_ACCEPTBTN 40002
#define ID_HELP_ABT 40003
BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
2. Change
this: int ret = DialogBox(GetModuleHandle, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);
to
this: int ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);
3. Add the message loop back in.
UpdateWindow(hwnd);
// Run the message loop. It will run until GetMessage() returns 0
while (GetMessage (&messages, NULL, 0, 0))
{
// Translate virtual-key messages into character messages
TranslateMessage(&messages);
// Send message to WindowProcedure
DispatchMessage(&messages);
}
// The program return-value is 0 - The value that PostQuitMessage() gave
return messages.wParam;
4. Change the ShowWindow command to this (i.e ignore the nCmdShow var passed to main by the OS
ShowWindow (hwnd, SW_SHOWNORMAL);
5. Add in class registration stuff:
WNDCLASSEX WndClsEx;
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WindowProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = szClassName;
WndClsEx.hInstance = hInst;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the window class, and if it fails quit the program
RegisterClassEx(&WndClsEx);
6. Add WindowProcedure forward declaration
*/
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <windows.h>
#include <cstdio>
#include "resource.h"
HINSTANCE hInst;
TCHAR *szClassName = _T("mClassName");
#define ID_FILE_EXIT 40001
#define IDC_ACCEPTBTN 40002
#define ID_HELP_ABT 40003
BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
/*default stuff, like including windows.h, etc... */
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
hInst = hThisInstance;
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/*default stuff, initializing fields of WNDCLASSEX struct */
WNDCLASSEX WndClsEx;
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WindowProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = szClassName;
WndClsEx.hInstance = hInst;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
/* Register the window class, and if it fails quit the program */
RegisterClassEx(&WndClsEx);
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Hello World"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
0, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Creating controls ... */
/* Make the window visible on the screen */
ShowWindow (hwnd, SW_SHOWNORMAL);
/* Default : message loop. It will run until GetMessage() returns 0 */
UpdateWindow(hwnd);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
HMENU hMenu, hSubMenu;
HICON hIcon, hIconSm;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&File");
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABT, "&About");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT) hSubMenu, "&Help");
SetMenu(hwnd, hMenu);
hIcon = (HICON) LoadImage(NULL, "iconBIG.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
if (hIcon)
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
hIconSm = (HICON) LoadImage(NULL, "iconSMALL.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
if (hIconSm)
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSm);
break;
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_ACCEPTBTN:
/* handling the controls */
break;
case ID_FILE_EXIT:
/* handling more controls ... */
PostQuitMessage(0);
break;
case ID_HELP_ABT:
int ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, myDialog);
/*PROBLEM: DialogBox returns -1*/
if (ret == -1)
{
DWORD dw = GetLastError(); // error 1812
char buffer[70];
sprintf(buffer, "Failed with %d", dw);
MessageBox(hwnd, buffer, "", MB_OK);
}
break;
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK myDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
}
Upvotes: 1
Reputation: 11588
GetModuleHandle
is a function. You can't pass a function's name to the HINSTANCE
parameter of DialogBox()
and expect it to work. In fact, I'm surprised it even compiled! The correct way to call it for the current executable is GetModuleHandle(NULL)
.
But there's a better way: the first parameter to WinMain()
is also the HINSTANCE
of your executable. Just store that in a global variable and use that directly instead.
Adding the following line before including <windows.h>
should help catch future errors like this one:
#define STRICT
Upvotes: 1