okay, so I have taken out the time to learn a but of the Win32 API to do with opening windows, and the code I came up with in the end I would think would work, but doesn't. I registered the window class, made all the things I have to, but when I run it, nothing happens... It would be a great help if someone could point out what I am doing wrong/missing.
#include <stdlib.h>
#include <iostream>
#include <Windows.h>
#pragma comment (lib, "wsock32.lib")
#define WNDCLASSNAME "wndclass"
bool quit = false;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd)
{
WNDCLASSEX WCE;
WCE.cbSize = sizeof(WNDCLASSEX);
WCE.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC|CS_DBLCLKS;
WCE.lpfnWndProc = WndProc;
WCE.cbClsExtra = 0;
WCE.cbWndExtra = 0;
WCE.hInstance = hinstance;
WCE.hIcon = NULL;//LoadImage()
WCE.hCursor = NULL;//LoadCursor(NULL, IDC_CROSS);
WCE.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
WCE.lpszMenuName = NULL;
WCE.lpszClassName = "KyleWindow";
WCE.hIconSm = NULL;
RegisterClassEx(&WCE);
HWND WindowHandle;
WindowHandle = CreateWindowEx(WS_OVERLAPPEDWINDOW, "KyleWindow", "Xerus", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hinstance, NULL);
ShowWindow(WindowHandle, SW_SHOWNORMAL);
UpdateWindow(WindowHandle);
std::cout<<"'Opened' Window"<<std::endl;
MSG msg;
while(!quit)
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
if(msg.message == WM_QUIT)
quit = true;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.lParam;
}
Use WS_EX_OVERLAPPEDWINDOW as the first parameter of your CreateWindowEx function (instead of WS_OVERLAPPEDWINDOW, which is not a valid extended window style).
instead of using WNDCLASSEX use WNDCLASS
change:
WNDCLASSEX WCE; to WNDCLASS WCE;
remove line:
WCE.cbSize = sizeof(WNDCLASSEX);
change:
RegisterClassEx(&WCE); to RegisterClass(&WCE);
The function int WINAPI WinMain must be before function LRESULT CALLBACK WndProc. Compilers read in order.
Related
So, I'm trying to learn how to make C/C++ Windows Desktop Applications, but I have come across a great issue, when creating a completely normal window, the cmd where the console application would run appears. Is there any way to make so that it doesn't even open? I've been seeing some methods, but they appear to hide the console, but the process is still there.Here is my code:
#define UNICODE
#define _UNICODE
#include <Windows.h>
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int nCmdShow) {
WNDCLASSW wc = { 0 };
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hInstance = hInstance;
wc.lpszClassName = L"windowClass";
wc.lpfnWndProc = WinProc;
if (!RegisterClass(&wc))
return 1;
HWND hWnd = CreateWindow(L"windowClass", L"Window 1",
WS_OVERLAPPEDWINDOW,
100, 100,
256, 256,
NULL, NULL, NULL, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, NULL, NULL)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
DefWindowProc(hWnd, msg, wParam, lParam);
}
}
I code in codeblocks.
Compiler = gcc version 4.9.2 (tdm-1)
I call MessageBox in WM_COMMAND.
When I press the button, The main window stop, But the MessageBox does not show.
I'm sure the WindowProc receive the button event!
But if I create a thread, and call MessageBox in the thread function, the MessageBox will show when I press the button. But if I call MessageBox in thread, Then then MessageBox can`t stop the main window.
How I can solve this problem?
#define IDI_BUTTON_1 10001
#define IDI_BUTTON_2 10002
#ifndef UNICODE
#define UNICODE
#endif
#include "resource.h"
#include "main.h"
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"mywindow";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
//wc.style = CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindow( CLASS_NAME,
L"Mywindow",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
250,
200,
NULL,
NULL,
hInstance,
NULL
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CREATE:
{
HWND hwndButton1 = CreateWindow( L"button" ,L"button1",
WS_CHILD|WS_VISIBLE,
10,
10,
75,
50,
hwnd,
(HMENU)IDI_BUTTON_1,
((LPCREATESTRUCT)lParam)->hInstance,
NULL);
HWND hwndButton2 = CreateWindow( L"button" ,L"button2",
WS_CHILD|WS_VISIBLE,
120,
10,
75,
50,
hwnd,
(HMENU)IDI_BUTTON_2,
((LPCREATESTRUCT)lParam)->hInstance,
NULL);
return 0;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDI_BUTTON_1:
MessageBoxW( hwnd, L"button1", L"button1", MB_ICONERROR|MB_DEFAULT_DESKTOP_ONLY );
break;
case IDI_BUTTON_2:
MessageBoxW( hwnd, L"button2", L"button2", MB_ICONERROR|MB_DEFAULT_DESKTOP_ONLY );
break;
}
return 0;
}
case WM_PAINT:
{
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
I'm rewriting a software I wrote, because of program size and performance problems; The code compiles fine but the window doesn't show up.
I've looked into other questions about this but none solved my problem, that's why I'm asking a new question, for sake of completeness, please explain what is wrong with the code and how to solve the problem.
I'm using Visual Studio 2013.
Here's the code:
WFrame.h
#pragma once
#include <Windows.h>
#include <tchar.h>
#include <wchar.h>
class WFrame
{
public:
WFrame();
WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle = WS_EX_OVERLAPPEDWINDOW);
~WFrame();
void show();
static LRESULT CALLBACK staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual LRESULT CALLBACK WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
private:
HWND hWnd;
int cmdShow;
};
WFrame.cpp
#include "WFrame.h"
WFrame::WFrame()
{
}
WFrame::WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle)
{
WNDCLASSEX wClass;
ZeroMemory(&wClass, sizeof(WNDCLASSEX));
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wClass.hIcon = NULL;
wClass.hIconSm = NULL;
wClass.hInstance = hInstance;
wClass.lpfnWndProc = (WNDPROC) WFrame::staticWindowProcedure;
wClass.lpszClassName = szClassName;
wClass.lpszMenuName = NULL;
wClass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wClass))
{
int nResult = GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
this->hWnd = CreateWindow(
szClassName,
szWindowTitle,
dwStyle,
nX,
nY,
nWidth,
nHeight,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
{
int nResult = GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
}
WFrame::~WFrame()
{
delete this;
}
void WFrame::show()
{
ShowWindow(this->hWnd, this->cmdShow);
UpdateWindow(this->hWnd);
}
LRESULT CALLBACK WFrame::staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WFrame* winptr = (WFrame*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (winptr == NULL) {
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
else {
return winptr->WindowProcedure(uMsg, wParam, lParam);
}
}
LRESULT CALLBACK WFrame::WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(this->hWnd);
break;
case WM_DESTROY:
if (!GetParent(this->hWnd))
PostQuitMessage(0);
break;
}
return DefWindowProc(this->hWnd, uMsg, wParam, lParam);
}
Main.cpp
#include <Windows.h>
#include "WFrame.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WFrame * frame = new WFrame(L"Window", L"Window", hInstance, nCmdShow, 0, 0, 1024, 700);
frame->show();
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Thanks to further answers.
I didn't see you assign a value to member variable cmdShow, so its default value is 0, which is SW_HIDE, so you should try the code below, see if the window can show up or assign cmdShow in WFrame initializer.
void WFrame::show()
{
ShowWindow(this->hWnd, SW_SHOW);
UpdateWindow(this->hWnd);
}
You are using WS_EX_OVERLAPPEDWINDOW for the dwStyle param of CreateWindow. This flag should actually be used for the dwExStyle param of CreateWindowEx. Use WS_OVERLAPPEDWINDOW instead.
Don't forget to delete frame; when you're done. You actually don't even need a pointer here. Just instantiate frame on the stack.
Also, you should return 0; for the window messages that you handled, instead of calling DefWindowProc.
I'm currently using this:
while (1)
{
if (GetAsyncKeyState(VK_F1))
{
//do something
}
}
to detect if a user presses a certain key, in this case F1. I've found that this eats up cpu usage by quite a bit, my question is, is there a better way to detect key presses?
The better way of doing this is using your WndProc(). So use standard WM_KEYDOWN/WM_KEYUP messages to handle keyboard input. Here is an example:
LRESULT CALLBACK WndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if ( wParam == VK_F1 )
{
// Do something here
return 0L;
}
break;
}
return DefWindowProc( hwnd, uMsg, wParam, lParam );
}
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;
// lots of other attrs ...
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
return 0;
// Step 2: Creating the Window
hwnd = CreateWindowEx(
...
g_szClassName,
...);
if(hwnd == NULL)
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;
}
I set Character set to Use Unicode Character Set but when show window, its title still have square character. How can I fix it? Thank!
#include <windows.h>
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wClass;
ZeroMemory(&wClass, sizeof(WNDCLASSEX));
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wClass.hIcon = NULL;
wClass.hIconSm = NULL;
wClass.hInstance = hInst;
wClass.lpfnWndProc = (WNDPROC)WinProc;
wClass.lpszClassName = L"Window Class";
wClass.lpszMenuName = NULL;
wClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wClass);
HWND hWnd = CreateWindowEx(
NULL,
L"Window Class",
L"/ce 但是,这样做并不能保证在对话框编辑器创建控件之前将加载所需的库。",
WS_OVERLAPPEDWINDOW,
200, 200, 300, 0, NULL, NULL, hInst, NULL);
ShowWindow(hWnd, nShowCmd);
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
I'm posting this as an answer, just because I can't put images in a comment ...
I just did exactly what you did, same code, Windows 8.1 x64 VS2012 UK English, and here's the result I get:
Unless you ignored the prompt to save your source file as a UNICODE file, you should have got the same result - I don't see that there are any other differences unless you have some strange settings in your Region/Language section of Control Panel.
If you still get the problem, you'll have to double-check all of your settings and maybe post more code and/or a dump of your compiler command line.