2017-08-15 6 views
3

私のアプリケーションは、Message.hppSendStructMessage()関数を使用して、着信メッセージによっていくつかのパネルに値を設定します。VCLアプリケーションはいつアプリケーション - >メインフォーム - >ハンドルを取得しますか?

SendStructMessage()に送信するには、有効なウィンドウハンドルが必要です。私はこのように、関数内SendStrucMessage()をカプセル化している

bool sendAppMessage(ApplicationMessageEnum msgID, void* s) 
{ 
    if(!Application || !Application->MainForm || !Application->MainForm->Handle) 
    { 
     Log(lError) << "Failed to get a valid handle when trying to send application message"; 
     return false; 
    } 
    HWND h = Application->MainForm->Handle; 

    AppMessageStruct data; 
    data.mMessageEnum = msgID; 
    data.mData = s; 

    LRESULT res = SendStructMessage(h, UWM_MESSAGE, 0, &data); 
    if(res) 
    { 
     Log(lError) << "Sending message: "<<msgID<<" was unsuccesful"; 
     return false; 
    } 

    return true; 
} 

のいずれかのMainFormのOnShowOnCreateイベントからこれを呼び出すしようとすると、Application->MainForm->HandleはまだNULLであるいずれかの場合のように、動作しません。

私の質問は、VCLアプリケーションの起動段階では、Application->MainForm->Handleが実際に作成されていることを確認できますか?

現在、私は有効なハンドルをチェックするタイマーをキックオフ:

void __fastcall TMain::WaitForHandleTimerTimer(TObject *Sender) 
{ 
    if(Application->MainForm->Handle) 
    { 
     WaitForHandleTimer->Enabled = false; 

     //Send a message to main ui to update sequence shortcuts 
     if(sendAppMessage(abSequencerUpdate) != true) 
     { 
      Log(lDebug)<<"Sending sequencer update to UI was unsuccesful"; 
     } 
    } 
} 

は、より良い方法はありますか?

+1

[この質問](https://stackoverflow.com/q/37614161/62576)とそのコメント(同様に答え)が役立ちます。 Delphiにはタグが付いていますが、VCLは完全にその言語で書かれており、同じ情報が適用されます。質問へのコメントには、ここで重要なその他のリンクが含まれています。 –

答えて

1

プロパティゲッターは、HWNDがまだ作成されていない場合は、プロパティが読み取られるときに新しいHWNDを作成します。 HWNDの作成中にエラーが発生すると、例外がスローされます。

Handleプロパティが決してリターンNULL(WindowHandleプロパティができ、けれども)ことができるので、だから、あなたの!Handle条件が常には、falseになります。全くSendMessage()/SendStructMessage()を使用していない、そうでない場合

bool sendAppMessage(ApplicationMessageEnum msgID, void* s) 
{ 
    if (!((Application) && (Application->MainForm) && (Application->MainForm->HandleAllocated()))) 
    { 
     Log(lError) << "Failed to get a valid handle when trying to send application message"; 
     return false; 
    } 

    AppMessageStruct data; 
    data.mMessageEnum = msgID; 
    data.mData = s; 

    LRESULT res = SendStructMessage(Application->MainForm->Handle, UWM_MESSAGE, 0, &data); 
    if (res) 
    { 
     Log(lError) << "Sending message: " << msgID << " was unsuccesful"; 
     return false; 
    } 

    return true; 
} 

bool sendAppMessage(ApplicationMessageEnum msgID, void* s) 
{ 
    if (!((Application) && (Application->MainForm))) 
    { 
     Log(lError) << "Failed to get a valid handle when trying to send application message"; 
     return false; 
    } 

    AppMessageStruct data; 
    data.mMessageEnum = msgID; 
    data.mData = s; 

    LRESULT res = SendStructMessage(Application->MainForm->Handle, UWM_MESSAGE, 0, &data); 
    if (res) 
    { 
     Log(lError) << "Sending message: " << msgID << " was unsuccesful"; 
     return false; 
    } 

    return true; 
} 

あなたはHandleが実際にそれを作成せずに作成されているかどうかを確認したい場合は

は、フォームの HandleAllocated()メソッドを使用します。あなたはまったく HWNDを必要とせずにフォームの割り当て WindowProcに直接メッセージを届けるであろう、代わりにフォームの Perform()メソッドを呼び出すことができます。

bool sendAppMessage(ApplicationMessageEnum msgID, void* s) 
{ 
    if (!((Application) && (Application->MainForm)) 
    { 
     Log(lError) << "Failed to get a valid handle when trying to send application message"; 
     return false; 
    } 

    AppMessageStruct data; 
    data.mMessageEnum = msgID; 
    data.mData = s; 

    LRESULT res = Application->MainForm->Perform(UWM_MESSAGE, 0, (LPARAM)&data); 
    if (res) 
    { 
     Log(lError) << "Sending message: " << msgID << " was unsuccesful"; 
     return false; 
    } 

    return true; 
} 

を別の方法として、sendAppMessage()からMainForm依存関係を削除することを検討します。代わりにApplication->Handleに送信し、Application->HookMainWindow()を使用してMainFormにコールバックメソッドを登録させることができます。

bool sendAppMessage(ApplicationMessageEnum msgID, void* s) 
{ 
    if (!((Application) && (Application->Handle)) 
    { 
     Log(lError) << "Failed to get a valid handle when trying to send application message"; 
     return false; 
    } 

    AppMessageStruct data; 
    data.mMessageEnum = msgID; 
    data.mData = s; 

    LRESULT res = SendStructMessage(Application->Handle, UWM_MESSAGE, 0, &data); 
    if (res) 
    { 
     Log(lError) << "Sending message: " << msgID << " was unsuccesful"; 
     return false; 
    } 

    return true; 
} 

__fastcall TMainForm::TMainForm(TComponent *Owner) 
    : TForm(Owner) 
{ 
    Application->HookMainWindow(&AppMessage); 
} 

__fastcall TMainForm::~TMainForm() 
{ 
    Application->UnhookMainWindow(&AppMessage); 
} 

bool __fastcall TMainForm::AppMessage(TMessage &Message) 
{ 
    if (Message.Msg == UWM_MESSAGE) 
    { 
     WindowProc(Message); 
     return true; 
    } 
    return false; 
} 
+0

提案された代替メッセージングの仕組みは本当に価値があるようです!特にPerformメソッド。 –

関連する問題

 関連する問題