所以我剛剛開始使用C++,並希望創建一個窗口,其中包含一個按鈕,用於啓動計數器的異步線程,該計數器的計數從5到0,表示耗時很長的任務。該數字應該已經顯示在窗口上,並在計數器計數時每秒更新一次。爲此,子線程必須以任何方式與主窗口線程的消息循環進行通信。 我想這將做到:C++從異步線程更新窗口窗口
- 發送的UpdateWindow與主窗口
- 發送的PostMessage的與主窗口
但在這兩種情況下,窗口的windowhandle的windowhandle不會得到更新。所以我懷疑是通過從主線程窗口句柄發送到子線程或發送UpdateWindow消息從子線程到主線程或兩者,或者我完全偏離軌道,everythig是錯誤的。
也許我的思維方式也是錯的,我應該用另一種方式來做,但我不知道我該怎麼開始。
#include "stdafx.h"
#include "Testproject.h"
#include <iostream>
#include <string>
#include <thread>
#define MAX_LOADSTRING 100
// Global variables:
HINSTANCE hInst; // Aktuelle Instanz
WCHAR szTitle[MAX_LOADSTRING]; // Titelleistentext
WCHAR szWindowClass[MAX_LOADSTRING];
HWND Button1;
int i = 0;
我的計數器:從VisualStudio2017
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
Button1 = CreateWindow(L"Button",L"Counter",WS_VISIBLE|WS_CHILD|WS_BORDER,0,40,100,20,hWnd,(HMENU) 1,nullptr,nullptr);
break;
}
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Menüauswahl bearbeiten:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case 1:
{
std::thread t1(counterr, hWnd);
t1.detach();
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PRINT:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
//TODO: Zeichencode, der hdc verwendet, hier einfügen...
RECT rc;
RECT rc2 = { 0, 0, 0, 0 };
int spacer = 3;
GetClientRect(hWnd, &rc);
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0, 0, 0));
std::wstring strOut = std::to_wstring(i); // or wstring if you have unicode set
DrawText(hdc, strOut.c_str(), strOut.length(), &rc, DT_SINGLELINE);
DrawText(hdc, strOut.c_str(), strOut.length(), &rc2, DT_CALCRECT);
rc.left = rc.left + rc2.right + spacer;
std::wstring strOut2 = L"heya";
DrawText(hdc, strOut2.c_str(), strOut2.length(), &rc, DT_TOP | DT_LEFT | DT_SINGLELINE);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
再次標準的東西
void counterr(HWND hWnd)
{
i = 5;
while(i>0)
{
i -= 1;
//UpdateWindow(hWnd);
PostMessage(hWnd, WM_PRINT, NULL, NULL);
Sleep(1000);
}
}
標準窗口和消息循環的東西和結束碼的
您不應該從其他線程更新UI線程。它會有未定義的行爲 – Asesh
那麼我應該怎麼做呢? – spaghetticode
此主題將回答您的問題:http://stackoverflow.com/questions/3783713/c-win32-executing-a-method-on-ui-thread-due-to-an-event-on-background-thread – Asesh