Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm trying to get a Windows/DirectX Input in my little program. I have tried it now for 2 days, but it is not working as expected.
It only recognizes the WM_KEYDOWN message if I asked for the WM_QUIT message before that. I can't find the solution to this weird problem. You can see the code below.
while(m_Running)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
MessageBox(NULL,"QUIT",NULL,MB_OK);
}
if(msg.message == WM_KEYDOWN)
{
MessageBox(NULL,"PRESS",NULL,MB_OK);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(Update() == false)
{
m_Running = false;
}
}
You should move your handlers into a win proc:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_QUIT:
// ....
break;
case WM_KEYDOWN:
// ....
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
And change your loop to:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Also, when you create your window class:
myclass.lpfnWndProc = WndProc;
Following on from the link I posted, I've downloaded Visual Studio Express 2013 and compiled run the following, tested it works.
This contains window and class creation, a message loop, and a windows procedure to process messages.
// Trim fat from windows
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Windows Procedure Message Handler
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Switch message, condition that is met will execute*/
switch (message)
{
case WM_CLOSE:
MessageBox(NULL, "QUIT", NULL, MB_OK);
PostQuitMessage(0);
break;
case WM_KEYDOWN:
MessageBox(NULL, "PRESS", NULL, MB_OK);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
// Main function
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX windowClass; //window class
HWND hwnd; //window handle
MSG msg; //message
/* Fill out the window class structure*/
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = "MyClass";
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
/* Register window class*/
if (!RegisterClassEx(&windowClass))
{
return 0;
}
/* Class registerd, so now create window*/
hwnd = CreateWindowEx(NULL, //extended style
"MyClass", //class name
"A Real Win App", //app name
WS_OVERLAPPEDWINDOW | //window style
WS_VISIBLE |
WS_SYSMENU,
100, 100, //x/y coords
400, 400, //width,height
NULL, //handle to parent
NULL, //handle to menu
hInstance, //application instance
NULL); //no extra parameter's
/* Check if window creation failed*/
if (!hwnd)
return 0;
bool done = false; //initialize loop condition variable
/* main message loop*/
while (!done)
{
PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
if (msg.message == WM_QUIT) //check for a quit message
{
done = true;
}
else
{
// Translate and dispatch to event queue
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I tried to make a common window, but when the window was created I found out that he was eating too much CPU. So this is the image of task manager when window is running'. How should I optimize my code to reduce processor load to allow app be able to work in the background mode without strong processor loading?
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void LError();
bool CreateMainWindow(HINSTANCE hinst, int width, int height);
WNDCLASSEX MC;
HWND Hmain;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
MSG msg;
if (!CreateMainWindow(hInstance, 800, 600)) {
LError();
}
ShowWindow(Hmain, nCmdShow);
UpdateWindow(Hmain);
HACCEL hAccel = LoadAccelerators(hInstance, NULL);
BOOL bRet = 0;
while (bRet = GetMessage(&msg, nullptr, 0, 0))
{
if (-1 == bRet) break;
if (!TranslateAccelerator(Hmain, hAccel, &msg))
{
if (!IsDialogMessage(Hmain, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
}
void LError() {
DWORD err = GetLastError();
// Translate ErrorCode to String.
LPTSTR Error = 0;
if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err,
0,
(LPTSTR)&Error,
0,
NULL) == 0)
{
MessageBox(NULL, TEXT("Error Translating"), TEXT("Error"), NULL);
}
if (Error = LPTSTR("The operation completed successefully")) {
return;
}
MessageBox(NULL, Error, TEXT("GetCurrentDirectory Error"), MB_OK | MB_ICONWARNING);
// Free the buffer.
if (Error)
{
::LocalFree(Error);
Error = 0;
}
}
bool CreateMainWindow(HINSTANCE hinst, int width, int height) {
LPCSTR Cname = "MainWindow";
MC.cbSize = sizeof(MC);
MC.style = CS_HREDRAW | CS_VREDRAW;
MC.style = 0;
MC.lpfnWndProc = WndProc;
MC.lpszMenuName = NULL;
MC.lpszClassName = Cname;
MC.cbWndExtra = NULL;
MC.cbClsExtra = NULL;
MC.hIcon = LoadIcon(NULL, IDI_WINLOGO);
MC.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
MC.hCursor = LoadCursor(NULL, IDC_ARROW);
MC.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
MC.hInstance = HINSTANCE(hinst);
if (!RegisterClassEx(&MC)) {
return 0;
}
RECT dspl;
GetWindowRect(GetDesktopWindow(), &dspl);
Hmain = CreateWindow(TEXT("MainWindow"),
LPCSTR("Calendar"),
WS_OVERLAPPED,
dspl.right - width, 0 ,
width, height,
(HWND)NULL,
NULL,
HINSTANCE(hinst),
NULL);
if (!Hmain) {
return 0;
}
SetWindowLong(Hmain, GWL_EXSTYLE, WS_EX_LAYERED);
SetLayeredWindowAttributes(Hmain, RGB(254, 254, 254), 150, LWA_ALPHA | LWA_COLORKEY);
return 1;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
HDC hDC;
PAINTSTRUCT PS;
RECT rect;
switch (Msg) {
case WM_PAINT:
break;
case WM_KEYUP:
switch(wParam) {
case VK_ESCAPE:
PostQuitMessage(NULL); break;
}break;
case WM_DESTROY:
PostQuitMessage(NULL);
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
From WM_PAINT documentation:
An application returns zero if it processes this message.
Either remove WM_PAINT or process it:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
}
Otherwise WndProc keeps getting WM_PAINT message. Alternatively you can put:
case WM_PAINT: return DefWindowProc(hWnd, Msg, wParam, lParam);
DefWindowProc will call BeginPaint/EndPaint to validate the client area.
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);
I have super simple WinApi program. Close button does not destroy process of the program. What should be added?
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hINSTANCE;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpstr,
int nCmdShow) {
// VARIABLES
TCHAR className[] = _T("win32api");
TCHAR windowName[] = _T("Protected Window");
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_INFORMATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = className;
wcex.hIconSm = LoadIcon(NULL, IDI_SHIELD);
if (!RegisterClassEx(&wcex)) {
MessageBox(NULL, _T("Cannot register window"), _T("Error"), MB_OK | MB_ICONERROR);
return 0;
}
HWND hWnd = CreateWindow(className,
windowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
300,
300,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd) {
MessageBox(hWnd, _T("Call to register windows isn't working"), _T("Error"), NULL);
return 1;
}
hINSTANCE = hInstance;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, hWnd, 0, 0) != 0 || GetMessage(&msg, hWnd, 0, 0) != -1) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.lParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uInt, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
switch (uInt) {
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 10, 20, _T("Text sample right here boyz."), _tcsclen(_T("Text sample right here boyz.")));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uInt, wParam, lParam);
break;
}
return 0;
}
If I add one more case
case WM_CLOSE:
PostQuitMessage(0);
break;
It doesnt close at all (pressing close button is not doing anything). Any other tips are very appreciated.
Your message loop is wrong, for two reasons:
you are calling GetMessage() twice. Don't do that! Think of what happens if you do. If the GetMessage() call on the left-hand side of || were to detect WM_QUIT (which it can't, see further below), it would return 0. Which would cause || to call the GetMessage() on the right-hand side, ignoring the WM_QUIT from the previous call and blocking the loop until a new message arrives later. You should call GetMessage() only once per loop iteration, and then act on the return value as needed:
BOOL bRet;
do
{
bRet = GetMessage(&msg, hWnd, 0, 0);
if (bRet == 0) break;
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
while (1);
However, you are also filtering messages by HWND (don't do that!), and so it will only return messages that are posted to the specified HWND via PostMessage(). PostQuitMessage() posts its WM_QUIT message to the input queue of the calling thread itself, not to the HWND. So the filtering will never see the WM_QUIT message. In order for WM_QUIT to break the loop, you need to stop filtering by HWND altogether, or at least make an unfiltered call periodically.
Your message loop should look like this instead. This is the standard message loop:
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Note in this case, there is no need to handle -1 from GetMessage()!.
To close the app, you need to destroy the window. Typically that's done in one of two ways:
Have your WM_CLOSE handler call DestroyWindow.
Have the DefWindowProc handle the message after you do your thing.
Your WndProc is a little out of the ordinary. I usually see them written as:
{
switch(msg)
{
case WM_CLOSE:
// prompt user, clean stuff up, etc.
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
// Other cases here. Most will fall out of the switch so that
// DefWindowProc can handle them (for other system notifications).
// Only return from the case if you really don't want anybody else
// to handle the message.
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
For specifics on WM_CLOSE, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx, which specifically says that you must call DestroyWindow or let DefWindowProc do it.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Code:
#include "CST CAL.h"
int SUSU()//Start Up
{
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0)
{
printf("WSASTATUP Falure: ", WSAGetLastError);
Sleep(1200);
return 1;
}
return 0;
}
int SR()//Send and Recive Data
{
return 0;
}
int DirX_Screen()//Render and Buffrer stuff and put on screen
{
return 0;
}
int SHUT()//ShutDown Program
{
return 0;
}
int GDI()//Get User Data Imput
{
return 0;
}
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//HERE IS CODE
if (SUSU() != 0)
{
return 1;
}int C = 0;
do{while(GetForegroundWindow() == GetForegroundWindow()){
int GeDI = GDI();
int SeR = SR();
int DirX = DirX_Screen();
if( GeDI != 0 || SeR != 0 || DirX != 0){C = 1;}else{printf("FR Suc\n");}
Sleep(0);
}}while (C == 0);
SHUT();
//HERE IS END OF CODE SPACE
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32PROJECT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT1));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32PROJECT1);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
This is originally a console application but then i use this template and just placed my code... my loop is supposed to print out the text but its not... it doesn't eve make the window. Please Help!
This is originally a console application but then i use this template
and just placed my code...
I wish things were that easy :)
You can't switch from console programming to the event driven one that easily. Maybe you should go through this tutorial.
my loop is supposed to print out the text but its not...
In winapi we usually use MessageBox to display text, or you could change the text of the static control or even pop a tooltip. This is done usually in response to a certain event, like button press for an example.
it doesn't eve make the window.
This happens because you have an infinite while loop before your call to InitInstance( ... ).
Your condition while(GetForegroundWindow() == GetForegroundWindow()) is always true so you never leave the while loop, thus never reaching the code that creates the window ( InitInstance( ... ) ).
Please Help!
After you go through the tutorial I recommended above, you will be able to recode properly your application.
I do not know enough about what you are trying to do, but I will try to offer you some advice:
Put your initialization code in WM_CREATE handler:
case WM_CREATE:
{
if( SUSU() != 0 )
return (LRESULT)-1;
else
return (LRESULT)0;
}
In your WM_DESTROY you should put your cleanup code ( note that WM_CLOSE sometimes does not get called! ):
case WM_DESTROY:
{
SHUT();
}
Your GDI() should be a part of an event, maybe a button press-I don't know it is entirely up to you. The same goes for SR(). They will be processed in WM_COMMAND handler.
I do not know DirectX so I do not know where to put your DirX_Screen(), but you could leave fancy graphics last and concentrate on functionality first.
Hopefully this helps a little.
I strongly advise you to go through that tutorial and to learn to read MSDN documentation.
Best regards and good luck!
I'm learning C++ and I have some questions. Some researches at msdn didn't help me. I wanna create two windows in one app. One window - dialog with options and another for graphic output. Here is the code that I use. But I have some problems with it:
Second window (for graphic) does not react at close, minimize, iconic buttons presses.
Message Boxes, when appear, are not in focus and not react at any mouse clicks, but in this time main window works fine.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
InitCommonControls();
if(FAILED(DialogWindow_OnCreate(hInstance)))
return 1;
if(FAILED(GraphicWindow_OnCreate(hInstance)))
return 1;
MSG msg;
memset(&msg, 0, sizeof(MSG));
while(msg.message != WM_QUIT)
{
while(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
OnUpdate();
}
GraphicWindow_OnClose();
return 0;
}
Creation of main window (Dialog):
HRESULT DialogWindow_OnCreate(HINSTANCE hInst)
{
g_hDialogWindow = CreateDialog(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, DialogWindow_WndProc);
if(!g_hDialogWindow)
return E_NOTIMPL;
UpdateWindow(g_hDialogWindow);
return S_OK;
}
Main window proc (Dialog):
INT_PTR CALLBACK DialogWindow_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
g_hDialogWindow = hWnd;
// Some init actions ...
return (INT_PTR)TRUE;
}
case WM_COMMAND:
int wmId, wmEvent;
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch(wmEvent)
{
case NULL: // Menu used
{
switch(wmId)
{
case IDC_BTN_1:
{
DialogWindow_OnBtn1();
MessageBoxA(NULL, "Some message", "Some title", MB_OK);
return (INT_PTR)TRUE;
} break;
case IDC_BTN_2:
{
DialogWindow_OnBtn2();
return (INT_PTR)TRUE;
} break;
// ...
case IDCANCEL:
{
// Close window
DefWindowProc(hWnd, WM_CLOSE, wParam, lParam);
} break;
case IDOK:
{
// Close window
DefWindowProc(hWnd, WM_CLOSE, wParam, lParam);
} break;
}
}
}
case WM_CLOSE:
DefWindowProc(hWnd, message, wParam, lParam);
return (INT_PTR)TRUE;
break;
case WM_DESTROY:
PostQuitMessage(0);
return (INT_PTR)TRUE;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return (INT_PTR)FALSE;
}
Second window (Graphic) creation:
HRESULT GraphicWindow_OnCreate(HINSTANCE hInst)
{
HWND g_hGraphicWindow = NULL;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = GraphicWindow_WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICO));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = _T("MyApp");
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
if(!RegisterClassEx(&wcex))
{
DWORD dwError = GetLastError();
if(dwError != ERROR_CLASS_ALREADY_EXISTS)
{
MessageBoxA(NULL, "GraphicWindow: RegisterClass() failed!", "Error", MB_OK | MB_ICONERROR);
return HRESULT_FROM_WIN32(dwError);
}
}
// Set window's initial size, but it might be changed later
int nDefaultWidth = 320;
int nDefaultHeight = 240;
RECT rc;
SetRect(&rc, 0, 0, nDefaultWidth, nDefaultHeight);
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
// Create the window
g_hGraphicWindow = CreateWindowA("MyApp", "GraphicWindow", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, (rc.right - rc.left), (rc.bottom - rc.top), 0,
0, hInst, 0);
if(!g_hGraphicWindow)
{
DWORD dwError = GetLastError();
MessageBoxA(NULL, "GraphicWindow: CreateWindow() failed!", "Error", MB_OK | MB_ICONERROR);
return HRESULT_FROM_WIN32(dwError);
}
UpdateWindow(g_hGraphicWindow);
return S_OK;
}
Graphic window proc:
LRESULT CALLBACK GraphicWindow_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_RETURN:
// Some actions ...
break;
case VK_ESCAPE:
// Some actions ...
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_CLOSE:
ShowWindow(hWnd, SW_HIDE);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Where is my problem? Help me, please.
I have the follow comments to make:
Do not call DefWindowProc in your dialog procedure. That could well be the main problem. See this example on MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644996.aspx#modeless_box
Your message loop is somewhat bogus. More on that later.
You should not be calling ANSI functions. Remove all A suffixes. You'll need to prefix string literals with L to specify wide strings. For instance, L"foo".
You should presumably pass the main window handle as hWndParent when you call CreateDialog. Otherwise, the modeless dailog will be unowned and so have its own taskbar button, and not appear always on top of the main window.
You should pass the main window handle as hWnd when you call MessageBox.
Looking in more detail at the message loop, you are not following the rules laid out in the documentation to CreateDialog, which states:
To support keyboard navigation and other dialog box functionality, the message loop for the dialog box must call the IsDialogMessage function.
So your message loop should be:
while(GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(g_hDialogWindow, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Note also that I switched to a GetMessage based loop. I don't think you need to run a hot loop for your needs. Using GetMessage allows your app's main thread to yield the CPU and block if it is idle.
In your Dialog Procedure, don't use DefWindowProc.
See: Dialog Box Default Message Processing.