前提・実現したいこと
WinAPIを用いて別スレッドで子ウィンドウを作成しようと思いました.
とりあえず以下のようなコードを書きましたが別スレッドでのcWindowProc (子ウィンドウのプロシージャ)の未解決外部シンボルのエラーで止まります.
がエラーの問題以前にこのコーディングの方針自体が危ういような気がします.
1)別スレッドで子ウィンドウを作成してもいいものなのでしょうか?
2)別のスレッドではメインのメッセージループを取得できるものなのでしょうか?
3)別のスレッドではそのスレッドのメッセージループをかけると子ウィンドウとして安全ではなくなりますよね?どのような手段をとればいいですか?
コード概要
スレッドへ渡すデータはPassHandleで親のHWNDとHINSTANCE
親ウィンドウプロシージャWM_CREATEで子ウィンドウ作成のスレッド作成
そのスレッドでWNDCLASSEX登録,ウィンドウ作成,子ウィンドウのプロシージャ作成
該当のソースコード
C
1//definition of structure 2#include <windows.h> 3 4struct PassHandle { 5 HWND hwnd; 6 HINSTANCE hInst; 7}; 8 9const wchar_t CHILD_CLASS_NAME[] = L"Child Class Name";
C
1//main 2#define UNICODE 3 4#include <windows.h> 5#include <process.h> 6#include "structure.cpp" 7 8LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); 9 10DWORD WINAPI cwthread(LPVOID); 11 12const wchar_t CLASS_NAME[] = L"CLASS"; 13 14HINSTANCE hInst; 15 16int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR nCmdLine, int nCmdShow) { 17 UNREFERENCED_PARAMETER(hPrevInstance); 18 UNREFERENCED_PARAMETER(nCmdLine); 19 20 hInst = hInstance; 21 22 WNDCLASSEX wc = { 23 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW, WindowProc, 24 0, 0, hInstance, 25 NULL, NULL,(HBRUSH)GetStockObject(WHITE_BRUSH), 26 NULL, CLASS_NAME, NULL 27 }; 28 29 RegisterClassEx(&wc); 30 31 HWND hwnd = CreateWindowEx( 32 0, CLASS_NAME, L"Template", WS_OVERLAPPEDWINDOW, 33 50, 50, 960, 525, 34 NULL, NULL, hInstance, NULL 35 ); 36 37 ShowWindow(hwnd, nCmdShow); 38 UpdateWindow(hwnd); 39 40 MSG msg = {}; 41 42 while (GetMessage(&msg, NULL, 0, 0)) { 43 TranslateMessage(&msg); 44 DispatchMessage(&msg); 45 } 46 47 return (int)msg.wParam; 48} 49 50LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 51 switch (uMsg) { 52 case WM_CREATE: 53 54 static PassHandle *mph; 55 mph->hwnd = hwnd; 56 mph->hInst = hInst; 57 58 _beginthreadex(NULL, 0, (_beginthreadex_proc_type)&cwthread, mph, 0, NULL); 59 break; 60 61 case WM_PAINT: 62 { 63 PAINTSTRUCT ps = {}; 64 HDC hdc = GetDC(hwnd); 65 66 BeginPaint(hwnd, &ps); 67 FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(BLACK_BRUSH)); 68 EndPaint(hwnd, &ps); 69 } 70 break; 71 72 case WM_DESTROY: 73 PostQuitMessage(0); 74 return 0; 75 } 76 77 return DefWindowProc(hwnd, uMsg, wParam, lParam); 78}
C
1//definition of the other thread 2#ifndef UNICODE 3#define UNICODE 4#endif 5 6#include <windows.h> 7#include "structure.cpp" 8 9LRESULT CALLBACK cWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 10 switch (uMsg) { 11 case WM_CREATE: 12 break; 13 14 case WM_PAINT: 15 { 16 PAINTSTRUCT ps = {}; 17 HDC hdc = GetDC(hwnd); 18 19 BeginPaint(hwnd, &ps); 20 FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(GRAY_BRUSH)); 21 EndPaint(hwnd, &ps); 22 } 23 break; 24 25 case WM_DESTROY: 26 PostQuitMessage(0); 27 return 0; 28 } 29 30 return DefWindowProc(hwnd, uMsg, wParam, lParam); 31} 32 33DWORD WINAPI cwthread(LPVOID *lpvoid) { 34 PassHandle *pd; 35 pd = (PassHandle*)lpvoid; 36 HWND hwnd = pd->hwnd; 37 HINSTANCE hInst = pd->hInst; 38 39 WNDCLASSEX wc = { 40 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW, cWindowProc, 41 0, 0, hInst, 42 NULL, NULL,(HBRUSH)GetStockObject(WHITE_BRUSH), 43 NULL, CHILD_CLASS_NAME, NULL 44 }; 45 46 RegisterClassEx(&wc); 47 48 HWND chwnd = CreateWindowEx( 49 0, CHILD_CLASS_NAME, L"Child", WS_CHILD | WS_OVERLAPPEDWINDOW, 50 5, 5, 960, 540, 51 hwnd, 0, hInst, 0 52 ); 53 54 ShowWindow(chwnd, SW_SHOW); 55 UpdateWindow(chwnd); 56 57 return 0; 58}
補足情報(FW/ツールのバージョンなど)
Windows10
VisualStudio2017 Community
よろしくお願いします.
回答2件
あなたの回答
tips
プレビュー