1

私はこれが多くの方法で尋ねられたのを見ましたが、実際に機能するコードスニップを見たことはありません.

新しいウィンドウとメッセージ ループを使用して新しいスレッドを作成するという素朴な試みを試みました。ウィンドウを開いてそのメッセージを処理する必要がある関数があり、既存のメッセージ ループがない (および他のウィンドウがない) または通常の mfc メッセージ ループまたは WTL メッセージ ループを使用してアプリケーションから呼び出すことができる環境で実行する必要があります。AddMessageLoop とモジュールについていくつか見ましたか? しかし、それは主なアプリケーション用だったようです。いずれにしても、WTL モジュールがある場合とない場合があります。基本的なメッセージ ループを備えたスタンドアロン ウィンドウが必要です。ウィンドウがまだ開いていない状態で WTL クラスを渡すと、ループと同じスレッドでウィンドウが開きます。クラスオブジェクトも新しいスレッドで作成する必要がありますか?

// does not work.... 
static DWORD WINAPI MyRunThread(__in LPVOID lpParameter)
{
CMessageLoop theLoop;
WTLsubclass *nav = (WTLsubclass *) lpParameter;

nav->CreateWindow(); 
int nRet = theLoop.Run();

return nRet;
}

CreateThread(0,0,MyRunThread,&nav,0,0);
4

2 に答える 2

0

SetWindowLongPtrおよびGetWindowLongPtr、これらを使用してウィンドウproc内からインスタンスにアクセスし、条件変数をに設定しますWM_ACTIVATE

クライアントコード:

// Create window, this setups the window and runs a message loop, its guts are ran in a different thread
createwindow();
// Wait to be shown, this presumes the existence of a mutext (m) and a condition_variable (cv) in your instance
std::unique_lock<std::mutex> lock(m);
cv.wait_for(lock, std::chrono::milliseconds(800));

ウィンドウのセットアップおよび作成中に、これをスレッドプロシージャに含めることができます。

// Create window (RegisterClass, CreateWindow, etc)
...
SetWindowLongPtr(hwnd, GWLP_USERDATA, /*your instance*/ ...);   
ShowWindow(hwnd, ...);
...
// Pump

ウィンドウプロシージャで:

...
switch(msg)
{
    case WM_ACTIVATE:
    {
        your_instance* inst = (your_instance*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
        inst->cv->notify_one();
    }
    break;
...
于 2012-06-04T08:58:48.287 に答える
0

必要な変更についてはコメントを参照してください。注意事項 1 は、& 演算子は WTL クラスでは機能しません。注意事項 2 は、イベントに名前を付けることはありません。不明な他のオブジェクトとリンクする場合、誰かが既に同じ名前を使用している可能性が高く、複数の CreateEvent() 呼び出しが使用されていても、Windows は同じ名前が同じイベントを意味すると判断します。名前も、おそらく異なるイベントの「エイリアシング」もありません。

「メイン」メッセージハンドラーでメッセージを処理したくない場合は、_Module は必要なく、メッセージループについて何も「伝える」必要もありません。独立したループを持つ独立したウィンドウが必要な場合は、以下を参照してください。

================================================== =

static DWORD WINAPI MyRunThread(__in LPVOID lpParameter)
{
CMessageLoop theLoop;
WTLsubclass *nav = (WTLsubclass *) lpParameter;

nav->CreateWindow(); 
SetEvent(WindowCreatedEvent) // signal event HANDLE type for worker thread

int nRet = theLoop.Run();

return nRet;
}

//CreateThread(0,0,MyRunThread,&nav,0,0); // & wont work on WTL class objects
// some genius overloaded the & operator on WTL class objects, just because in C++ you can

//Workaround to get address of WTL class object
CLASSnav nav[1];
CLASSnav *pnav = nav; // because arrays is address of first element.
CreateThread(0,0,MyRunThread,pnav,0,0);
于 2012-04-22T15:47:48.340 に答える