Jak ukryć okno konsoli

0

Niedawno zacząłem się interesować tworzeniem interfejsów graficznych w WinAPI, ale mam jeden problem - poza właściwym oknem otwiera się niepotrzebne okno konsoli. Czy instnieje sposób, aby je ukryć? Przykladowa aplikacja mająca ten problem (test przycisków):

#include <windows.h>

HWND WindowHandle;
HWND Button1Handle;
HWND Button2Handle;
MSG WindowIncomingMessage;

LRESULT CALLBACK WindowProcedure(HWND WindowHandle,UINT WindowMessage,WPARAM wparam,LPARAM lparam){
	switch(WindowMessage){
		case WM_COMMAND:
			if(((HWND)lparam)==Button1Handle){
				MessageBox(WindowHandle,"Button 1 clicked.","Button test",MB_OK|MB_ICONINFORMATION);
			}else if(((HWND)lparam)==Button2Handle){
				MessageBox(WindowHandle,"Button 2 clicked.","Button test",MB_OK|MB_ICONINFORMATION);
			}
			break;
		case WM_CLOSE:
			DestroyWindow(WindowHandle);
			break;
		case WM_DESTROY:
			PostQuitMessage(NULL);
			break;
		default:
			return DefWindowProc(WindowHandle,WindowMessage,wparam,lparam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	LPSTR WindowClassName="4cb579da1272f7b7281b9118fe479679";
	WNDCLASSEX WindowClass;
	WindowClass.cbSize=sizeof(WNDCLASSEX);
	WindowClass.style=NULL;
	WindowClass.lpfnWndProc=WindowProcedure;
	WindowClass.cbClsExtra=NULL;
	WindowClass.cbWndExtra=NULL;
	WindowClass.hInstance=hInstance;
	WindowClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	WindowClass.hCursor=LoadCursor(NULL,IDC_ARROW);
	WindowClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
	WindowClass.lpszMenuName=NULL;
	WindowClass.lpszClassName=WindowClassName;
	WindowClass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
	if(!RegisterClassEx(&WindowClass)){
		return 1;
	}
	WindowHandle=CreateWindowEx(WS_EX_CLIENTEDGE,WindowClassName,"Button test",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,280,340,NULL,NULL,hInstance,NULL);
	if(!WindowHandle){
		return 1;
	}
	Button1Handle=CreateWindowEx(NULL,"BUTTON","Button 1",WS_CHILD|WS_VISIBLE,20,20,220,115,WindowHandle,NULL,hInstance,NULL);
	Button2Handle=CreateWindowEx(NULL,"BUTTON","Button 2",WS_CHILD|WS_VISIBLE,20,155,220,115,WindowHandle,NULL,hInstance,NULL);
	ShowWindow(WindowHandle,nCmdShow);
	UpdateWindow(WindowHandle);
	while(GetMessage(&WindowIncomingMessage,NULL,NULL,NULL)){
		TranslateMessage(&WindowIncomingMessage);
		DispatchMessage(&WindowIncomingMessage);
	}
	return 0;
}
5

Stwórz projekt ponownie, tym razem nie wybierając Console Application po czym przekopiuj źródła.

4

Ewentualnie gcc z parametrem -mwindows

gcc -mwindows main.c

Albo
otwierasz plik binarnie i na offsecie 0xDC, zmieniasz bajt z 0x3 na 0x2, czyli gasisz zapalasz pierwszy bit.

3
Manna5 napisał(a):
#include <windows.h>

HWND WindowHandle;
HWND Button1Handle;
HWND Button2Handle;
MSG WindowIncomingMessage;

Nie potrzebujesz globalnie ani WindowHandle ani WindowIncomingMessage. Przenieś je do WinMain.
Buttonów też dałoby się uniknąć ale na razie zostawmy.

		case WM_CLOSE:
			DestroyWindow(WindowHandle);
			break;

To samo robi defaultowy WM_CLOSE, więc możesz to wyciąć. Własny WM_CLOSE się przydaje jeśli chcesz pokazać message boxa z pytaniem "czy na pewno" chcesz zamknąć okno, albo czy chcesz zapisać zmiany.

  case WM_DESTROY:
  	PostQuitMessage(NULL);
  	break;

Właściwie to tu powinno być 0 a nie NULL, bo parametr jest typu int a nie wskaźnik.

	while(GetMessage(&WindowIncomingMessage,NULL,NULL,NULL)){
``

Dwa ostatnie parametry GetMessage są typu UINT, więc wypadałoby przekazywać 0 a nie NULL (bo NULL sugeruje że to wskaźniki).
Pól WNDCLASSEX i wywołań CreateWindowEx już mi się nie chce sprawdzać, ale tam też się znajdą niepotrzebne NULLe.

		TranslateMessage(&WindowIncomingMessage);
		DispatchMessage(&WindowIncomingMessage);
	}
	return 0;

Tu zamiast return 0 powinno być return WindowIncomingMessage.wParam. Będzie to ta sama wartość którą wyżej przekazujesz do PostQuitMessage.

Nigdy nie widziałem by ktoś używał tak długiej nazwy zmiennej dla message'a; zawsze widuję po prostu MSG msg.

0

@Azarien: Nulle poprawię, a globalny WindowHandle jest potrzebny do wyświetlania okien informacyjnyjnych w kontekście okna głównego.

3

Przecież dostajesz okno jako parametr w WindowProcedure. Tej zmiennej globalnej tam nawet nie używasz, bo nazwałeś parametr tak samo.

1 użytkowników online, w tym zalogowanych: 0, gości: 1