This question already has answers here:
How to stop a program compiled with MinGW (g++) from opening a console window in windows
(2 answers)
Closed 9 years ago.
I've copy-pasted following skeleton of a simple C++ WinAPI application. It works, but creates an additional console window along with GUI one. How to get rid of it? I am using GCC from MinGW.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static char sClassName[] = "MyClass";
static HINSTANCE zhInstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX WndClass;
HWND hwnd;
MSG Msg;
zhInstance = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = NULL;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = zhInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = sClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&WndClass)) {
MessageBox(0, "Error Registering Class!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_STATICEDGE, sClassName, "db Tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
320, 240, NULL, NULL, zhInstance, NULL);
if(hwnd == NULL) {
MessageBox(0, "Error Creating Window!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
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) {
switch(Message) {
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
Just use the -mwindows option to compile a GUI application. The default, -mconsole, creates a console application.
The default heuristic used by the MS linker is: if your program has a main function it is a console program but if it has a WinMain function it is a GUI one. But that is not used by the GNU tools. They create a console program by default.
Related
I am building an app with WinAPI that consists of basically two main parts: a panel on the left hand that is always shown and an area on the right that changes based on which screen is shown. Currently the left-hand, static area is just being drawn onto the main window; however, for I don't believe that I can simply draw the right area onto the main window as it needs to change. Therefore, I believe that I need to create windows there and just control what is shown by controlling its visibility. I read a lot about the Multiple Document Interface in the MSDN, but I'm not sure if that is what I am looking for. Specifically, I don't want the child windows to act like real windows, meaning I don't want them to have a title or icon or be able to be minimized, closed, resized, or moved. Basically, I want them to just be frames that hold controls/D2D geometry. What would be the best way to go about implementing this?
As Remy said, you only need to re-register a new window and then create it as a subclass in the main window. You don't need to set the title and maximize and minimize buttons in setting the style, and you can also decide by yourself whether you need to deal with the WNDPROC function of the subclass.
Here is a sample(In order to display the child window, I set its background to black.):
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK cldWndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR szCmdLine, _In_ int iCmdShow)
{
static TCHAR szAppName[] = TEXT("hello windows");
static TCHAR cldwndName[] = TEXT("test app");
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,
100,
100,
800,
600,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
WNDCLASS cldclass;
cldclass.style = CS_HREDRAW | CS_VREDRAW;
cldclass.lpfnWndProc = cldWndProc;
cldclass.cbClsExtra = 0;
cldclass.cbWndExtra = 0;
cldclass.hInstance = hInstance;
cldclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
cldclass.hCursor = LoadCursor(NULL, IDC_ARROW);
cldclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
cldclass.lpszMenuName = NULL;
cldclass.lpszClassName = cldwndName;
if (!RegisterClass(&cldclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
}
HWND hwnd1 = CreateWindow(cldwndName,
NULL,
WS_CHILD|WS_VISIBLE,
400,
200,
200,
300,
hwnd,
NULL,
hInstance,
NULL);
ShowWindow(hwnd1, iCmdShow);
UpdateWindow(hwnd1);
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK cldWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
It works for me:
I would like to prevent some action in my app using winapi for example I would like to block moving my window app. How can I do this?
I try this:
if( pWindowsMessage->message == WM_MOVING )
{
return 1;
}
else if(pWindowsMessage->message == WM_MOVE)
{
return 1;
}
But it doesn't work.
Other example: How to prevent close the window?
if( pWindowsMessage->message == WM_CLOSE )
{
return 1;
}
It works. But is it a good solution?
Of course the first and the second example are in the function which get messages.
You can block messages in different areas by handling WM_NCLBUTTONDOWN messages.
And According to WM_NCHITTEST,we can handle events in different regions.
Here is a sample:
#include <Windows.h>
#include <cassert>
#include <cstdlib>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("hello 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)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_NCLBUTTONDOWN:
if (wParam == HTCAPTION || (wParam >= HTLEFT && wParam < HTBORDER))
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
I was trying coding a simple Win32 GUI Application using Eclipse CDT (Eclipse used in C++) but it throws an error which says:
conflicting declaration of C function 'int WinMain(HINSTANCE, int, LPSTR, int)
My code:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
WNDCLASSEX cWindow;
HWND hWnd;
MSG Msg;
cWindow.cbSize = sizeof(WNDCLASSEX);
cWindow.lpszClassName = "cls";
cWindow.lpfnWndProc = WndProc;
cWindow.lpszMenuName = NULL;
cWindow.hInstance = hInstance;
cWindow.style = CS_OWNDC;
cWindow.hIcon = LoadIcon(NULL, IDI_APPLICATION);
cWindow.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
cWindow.hCursor = LoadCursor(NULL, IDC_ARROW);
cWindow.hbrBackground = (HBRUSH)3;
cWindow.cbClsExtra = 0;
cWindow.cbWndExtra = 0;
if(!RegisterClassEx(&cWindow))
MessageBox(NULL, "Error registring window class!", "Fatal error", MB_OK | MB_ICONERROR);
hWnd = CreateWindowEx(0, "cls", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
640, 640, HWND_DESKTOP, NULL, hInstance, NULL);
while(GetMessage(&Msg, NULL, NULL, NULL)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
DestroyWindow(hWnd);
return 0;
}
It is on C++ language, and I'm using MinGW compiler
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.
I have this very simple C++ class which just opens a blank Windows window, but I've noticed that everytime I double click the .exe, it opens the window, but it also opens a command prompt window too.
Is there a quick easy & simple way to stop this command prompt window from happening?
Cheers in advance,
KS.
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_LBUTTONDOWN:
{
char szFileName[MAX_PATH];
HINSTANCE hInstance = GetModuleHandle(NULL);
GetModuleFileName(hInstance, szFileName, MAX_PATH);
MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
}
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 = 1;
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,
"WinApp-2",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
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;
}
Just link with the /SUBSYSTEM:WINDOWS option instead of /SUBSYSTEM:CONSOLE.
If you're currently letting the compiler call the linker, you may want to pass /c to cl.exe to compile only, and then call link.exe /SUBSYSTEM:WINDOWS on the resulting object file(s).