VC how to create a window interface in Windows console application

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/qiuchangyong/article/details/91127039

In VC, we can create two types of applications, one is only a black window, dos style under the console, can only use the keyboard to input interaction; the other is the Windows interface window, with the mouse point to point operation interaction. The former began by main function, namely the entry point of the program, which it, through WinMain beginning of the program execution. A doubt what is the difference between these two approaches caused ye so much? Windows is not writing Windows programs, you must define WinMain function?

The answer: Not necessarily! For example, the program can OpenCV pop-up window to display the picture, there are other control interface can pop up, it is the program's main entry point function. Another example Qt application is started from the main function of. Application under the main mac is the beginning, there are many other examples, these have proved one thing: even without WinMain, main entry point function can build Windows Forms applications. So why should Microsoft do this distinction, I think it only did it "Baimafeima" indicates that this is a novelty Bale.

So how do you create a Window Forms interface from a console application?

A Windows window interface program, the need forHINSTANCE hInstance,这个从哪里来,WinMain的参数里带了,而main的参数里没有,怎么办?可以通过GetModuleHandle获得,有了hInstance,下面就可以创建窗口,建立消息循环。这样创建的窗口程序还是有个控制台黑窗口存在,可以通过printf把一些log答应到里面。但如果不希望出现黑窗口呢,可以通过

HWND hWnd = ::GetConsoleWindow();
::ShowWindow(hWnd, SW_HIDE);

将其隐藏掉。这样做不是那么完美,因为程序开始的时候有个黑窗口一闪就消失了。解决的办法就是下面这一句:

#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

suchGetConsoleWindow得到的就是NULL,说明系统默认没有创建控制台的黑窗口。

最后贴上全部代码:

#include <Windows.h>
#include <iostream>
using namespace std;

#define MAX_LOADSTRING 100

// 全局变量: 
HINSTANCE hInst;                                // 当前实例
WCHAR* szTitle=TEXT("在main函数中创建的窗口");                  // 标题栏文本
WCHAR* szWindowClass=TEXT("WindowClass");            // 主窗口类名

ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

//下面这一句很重要,如果希望不出现控制台黑窗口,就保留它;如果希望保留控制台黑窗口,就注释掉它
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

int main()
{
	/*
	HWND hWnd = ::GetConsoleWindow();
	if (hWnd) {
		cout << hWnd << endl;
		::ShowWindow(hWnd, SW_HIDE);
		::MessageBox(NULL, TEXT("这是一个在控制台应用程序下创建窗口的演示"), TEXT("MessageBox"), MB_OK);
	}
	*/
    HINSTANCE hInstance = ::GetModuleHandle(NULL);
    cout << hInstance << endl;

    MyRegisterClass(hInstance);

    // 执行应用程序初始化: 
    if (!InitInstance(hInstance, SW_SHOW))
    {
        return FALSE;
    }

    //HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32TEST));

    MSG msg;

    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;    
}


//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW 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, NULL);
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, NULL);

    return RegisterClassExW(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释: 
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance; // 将实例句柄存储在全局变量中

    HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{    
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &ps);
			// TODO: 在此处添加使用 hdc 的任何绘图代码...
			EndPaint(hWnd, &ps);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/qiuchangyong/article/details/91127039