これは Windows の質問のように思えますが、私の質問の本質は実際には C++11 (または MS C++0x TR1) です。std::function
それは、オブジェクトとそのライフサイクルを渡すことです。
Windows PostMessage
API を介した非同期実行用の汎用フレームワークが必要です。これは、状況により、現在のメッセージ処理を終了し、タスクをメッセージ キューに登録する必要がある場合です。
フレームワークは、静的関数へのポインター ( 内WPARAM
) とコンテキストへのポインター( 内)LPARAM
で正常に動作しています。これには、「this」ポインターと他のコンテキストが含まれています。
私はそれを次のレベルに引き上げ、バインドと関数構造を使用したいと考えています。私はVisual Studio 2010を使用しています(つまりstd::function
、存在しますがTR1です)。
これまでのところ、これは私が持っているものです:
私はWM_ASYNC_TASK
教科書で a を登録していますが、Windows の手順 (私は実際に WTL を使用しています) は正常に動作しています。PostMessage
正常に動作し、メッセージは最終的にandで正しく、期待どおりに到達onAsyncTask
します。wparam
lparam
const UINT WM_ASYNC_TASK = RegisterWindowMessage(L"Async-Task");
これCPlugin
は、タスクを送信する場所です。メッセージをCHiddenWindow
受け取るウィンドウの実装はどれですか。onAsyncTask
に関数を に転送してもらいたいのですがCPlugin
。hwnd
ウィンドウのハンドルです。
CPlugin
私は:
void CPlugin::ShowMessageBox( void* arg ) {
wchar_t* text = (wchar_t*)arg;
MessageBox( NULL, text, L"Title", MB_OK )
}
void CPlugin::Sender( ) {
std::function<void(void*)> f = std::bind( &CPlug::ShowMessagebox,
this,
std::placeholders::_1 );
PostMessage( hwnd, WM_ASYNC_TASK, (WPARAM)f, (LPARAM)"Hello!!" );
}
CHiddenWindow の WM_ASYNC_TASK メッセージのハンドラーで次のことを行いました。
void CHiddinWindow::onAsyncTask( WPARAM wparam, LPARAM lparam, /* more arguments */ )
{
std::function<void(void*)> f = (std::function<void(void*)>)wparam;
void* arg = lparam;
f( arg );
}
質問:
- 現在、f を WPARAM にキャストしようとすると、
PostMessage
(WPARAM
は基本的には long です) 内でコンパイラが文句を言います。 f
:のアドレスを取得していれば問題ありません(WPARAM)&f
。- これは、f のライフサイクルについて別の問題を提起します。どのように保管すればよいですか?
- 渡すとき(私の欲求ではなく、外に置いて
&f
おく)、逆参照しようとすると、でアクセス違反が発生します。f
Sender()
onAsyncHandler
f
- ライフサイクルについて、どうにかして f を制御下に置くことはでき
std::shared_ptr
ますか? - wparam で関数 (私の場合はテキスト) に引数を渡す本当の理由はありません。オブジェクトのテキスト部分を持つ方法があるべきだと思いますが
std::function
、構文で失敗します。
私が言ったように、私は可変個引数テンプレートの前に VS 2010 を使用しています。Microsoft には、C++0x の TR1 実装があります。現在利用できないため、ブーストを含まないソリューションを探しています。
ありがとうございました!