C ++在新线程中从控制台创建新窗口(Win32)

时间:2016-07-13 17:20:39

标签: c++ multithreading winapi console windows-console

工作环境:

我正在使用VS 2015和win32控制台。

概述:

我正在创建一个新窗口,作为工作线程来执行一些无法在控制台中完成的功能。

创建新窗口并完成任务的代码运行良好。然而它冻结了控制台。

我有代码从控制台创建一个线程,并在控制台未冻结时完成任务。这也很有效。

问题:

我无法加入这两段代码,我想在线程中运行新窗口,因此它不会阻止控制台。

代码:

=============== int main ====================== < / p>

启动帖子

x = 0;
hPrintMutex = CreateMutex(NULL, false, NULL);

HANDLE hThread1 = (HANDLE)_beginthread(printNumber, 0, &x);
WaitForSingleObject(hThread1, INFINITE);

制作新窗口

WNDCLASSEX wndclass = { sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
0, 0, GetModuleHandle(0), LoadIcon(0,IDI_APPLICATION),
LoadCursor(0,IDC_ARROW), HBRUSH(COLOR_WINDOW + 1),
0, myclass, LoadIcon(0,IDI_APPLICATION) };

if (RegisterClassEx(&wndclass))
{
    HWND window = CreateWindowEx(0, myclass, "title",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0);
    if (window)
    {
        ShowWindow(window, SW_SHOWDEFAULT);
        MSG msg;
        while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
    }
}

======== 在主要之外 ============================== =========

在新线程中执行某些操作的代码

(*实际内容只是一个例子,它们将被删除并替换为窗口代码*)

void printNumber(void* pInt)
{

int* xp = (int*)pInt;
while (*xp<100)
{
    WaitForSingleObject(hPrintMutex, INFINITE);

    ++*xp;
    cout << *xp << endl;

    ReleaseMutex(hPrintMutex);
    Sleep(10);
}


}

用于创建新窗口并执行某些操作的代码

long __stdcall WindowProcedure(HWND window, unsigned int msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{

case something: { 

}
default: 

    return DefWindowProc(window, msg, wp, lp);
}
}

有什么想法?感谢。

*****解决方案*****

请参阅我在下面发布的解决方案,测试并运行。

2 个答案:

答案 0 :(得分:1)

得到了这个工作,我想我会发布它来帮助那些也开始有困难的人

在您的主要开始线程

HANDLE myhandle;

myhandle = (HANDLE)_beginthreadex(0, 0, &mythread, 0, 0, 0);

如果您的控制台在循环中运行,那么您不需要调用WaitForSingleObject,如果不是,则需要调用它以便控制台不会关闭。

在主之外

创建线程,在线程内部创建窗口

unsigned int __stdcall mythread(void* data)
{

cout << "/n created monitor window /n";

const char* const myclass = "myclass";

WNDCLASSEX wndclass = { sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
    0, 0, GetModuleHandle(0), LoadIcon(0,IDI_APPLICATION),
    LoadCursor(0,IDC_ARROW), HBRUSH(COLOR_WINDOW + 1),
    0, myclass, LoadIcon(0,IDI_APPLICATION) };

if (RegisterClassEx(&wndclass))
{
    HWND window = CreateWindowEx(0, myclass, "title",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0);
    if (window)
    {
        ShowWindow(window, SW_SHOWDEFAULT);
        MSG msg;
        while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
    }
}

return 0;
}

也在主窗外,新窗口

long __stdcall WindowProcedure(HWND window, unsigned int msg, WPARAM wp, LPARAM lp)
{ 
switch (msg)
{

case checksomethinghere: { 

}
default: // fall thru 

    return DefWindowProc(window, msg, wp, lp);
}
}

现在,您可以将监视器窗口与控制台配合使用,而不会阻止控制台活动。

经过测试,运作良好。

根据我的阅读,您不必担心为创建的线程调用CloseHandle,因为当控制台关闭时,它将终止线程和您创建的窗口。

在我的场景中,窗口和线程在控制台应用程序运行的整个时间内保持活动状态。

答案 1 :(得分:0)

是否可以向 UI 线程发送消息?

完整示例 + PostMessage 到 UI 线程?

#include <Windows.h>
#include <process.h>

UINT test_message = 0;
long __stdcall WindowProcedure(HWND window, unsigned int msg, WPARAM wp, LPARAM lp)
{
    if (test_message == msg) {
        printf("Got it !\n"); // to console
        return 0;
    }
    else
        return DefWindowProc(window, msg, wp, lp);
}
static HWND window = NULL;
void SendMeMessage(HWND _window)
{
    window = _window;
    test_message = RegisterWindowMessage("TEST");
    PostMessage(window, test_message, 0, 0);
}

unsigned int __stdcall mythread(void* data)
{
    const LPCSTR myclass = "myclass";

    WNDCLASSEX wndclass = { sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
        0, 0, GetModuleHandle(0), LoadIcon(0,IDI_APPLICATION),
        LoadCursor(0,IDC_ARROW), HBRUSH(COLOR_WINDOW + 1),
        0, myclass, LoadIcon(0,IDI_APPLICATION) };

    if (RegisterClassEx(&wndclass))
    {
        window = CreateWindowEx(0, myclass, "title",
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0);
        if (window)
        {
            SendMeMessage(window);
            ShowWindow(window, SW_SHOWDEFAULT);
            MSG msg;
            while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
        }
    }

    return 0;
}

int main()
{
    HANDLE myhandle;

    myhandle = (HANDLE)_beginthreadex(0, 0, &mythread, 0, 0, 0);
    // ...