2016-10-09 4 views
1

これはやや難解な質問ですが、私が実際に使っているDMスクリプトモジュールには実際に影響します。カスタムモーダルダイアログを使用して、遅延メインスレッドタスクによって検出されたエラー状態をユーザーに警告しようとしています。ほとんどの場合、これはうまくいきますが、エラーメッセージが表示されたときにDMアプリケーションウィンドウが最小化されると、DMはフォアグラウンドアプリケーションとして復元されたときに異常な状態になります。モーダルダイアログは表示されませんが、それでも 'enter'または 'esc'キーストロークで終了するまでは、DM内のユーザーアクションを禁止します。DMアプリケーションウィンドウが最小化されたときに遅延タスクによってポストされたモーダルダイアログを処理する方法は?

は、以下のサンプルコードは、GMS 2以降で動作します同等以上の回避策があり、問題を実証し、

GMS 1で働いていたソリューションを言及しますか?

+0

面白いです。私はそれが解決されていないことを知っているのではないかと危惧しています。MSのウィンドウ管理の一部であると見られ、スクリプトは何もできないかもしれません。しかし、私はGMS 3にこの問題がないことを確認したところです。 – BmyGuest

+0

非常に "角を曲がった"アイデア:コマンドライン(またはその他の実行可能ファイル)によって最小化されたアプリケーションウィンドウを復元/最大化する方法を知っていますか? )?私はインターネット検索をすばやく見つけることができませんでしたが、そうした場合、LaunchExternalProcess()コマンドを使用した解決策があるかもしれません。基本的には、アプリケーションウィンドウが最小化されている間にGMS 2上にダイアログを表示すると、そのウィンドウには「親」ウィンドウが割り当てられません。だからあなたは、ポーズの時にアプリケーションのウィンドウが表示されるようにする必要があります.... – BmyGuest

+0

@BmyGuest - あなたのコメントやアイデアのために多くの感謝。この問題はGMS 3では発生していないと聞いてよかったです。このニュースは私がカスタムモーダルダイアログで抱えていた他の問題を解決する最新バージョンへのアップデートを促しました。特に、LaunchExternalProcess()についてのヒントをお寄せいただきありがとうございます。私はあなたの「隅々まで」のアイデアを使って解決策を見つけ、それを私自身の質問に対する答えとして掲示します。 –

答えて

1

解決策をLaunchExternalProcess()関数と外部プログラムに基づいて提案すると、答えへのパスが提供されます。 AutoHotKeyと呼ばれる無料のオープンソースのWindowsマクロ作成パッケージを使用することで、RestoreDM.exeという非常にコンパクトな実行可能ファイルを作成することができました。この実行可能ファイルをDMスクリプトから簡単にアクセスできるフォルダに配置することで、LaunchExternalProcessAsync()を使用して起動して、カスタムダイアログをポストする前にDMアプリケーションウィンドウが復元されていることを確認できます。以下は、オリジナルのテストスクリプトの修正版この解決策を説明し、AutoHotkeyをスクリプトの詳細を提供している:

class DeferredAlertTask 
{ 
    Number deferredTaskID; 

    DeferredAlertTask(Object self) 
    { 
     Number taskDelay_sec = 5; 
     String message = "Click OK and then minimize the DM app window.\n"; 
     message += "After 5 seconds, select DM on the task bar to restore it.\n"; 
     message += "Dialog will be invisible, must hit 'enter' or 'esc' to go on."; 
     OKDialog(message); 

     deferredTaskID = AddMainThreadSingleTask(self, "Task", taskDelay_sec); 
    } 

    void Task(Object self) 
    { 
     String banner = "Error dialog"; 
     String message = "Error message details."; 

     // Create the dialog box descriptor TagGroup 
     TagGroup dialogItemsSpec; 
     TagGroup dialogSpec = DLGCreateDialog(banner, dialogItemsSpec); 

     // Create and add the content box and text field to the layout 
     TagGroup contentBoxItemsSpec; 
     TagGroup contentBoxSpec = DLGCreateBox(contentBoxItemsSpec); 
     TagGroup contentLabelSpec = DLGCreateLabel(message); 
     contentBoxItemsSpec.DLGAddElement(contentLabelSpec); 
     dialogItemsSpec.DLGAddElement(contentBoxSpec); 

     // If the DM app window has been minimized, 
     // this modal dialog will be invisible, 
     // but it will still inhibit further user action 
     // within DM as it awaits 'esc' or 'enter'. 

     // The following is a remedy that works in GMS1, but not in GMS2 
     // GetApplicationWindow().WindowSelect(); 

     // For GMS2, we can use an executable that restores the DM app window. 
     // The lines below launch RestoreDM.exe, placed in C:\ProgramData\Gatan, 
     // where RestoreDM is an executable of the following AutoHotKey script: 
     // IfWinNotActive, Digital Micrograph 
     //  WinRestore, Digital Micrograph 
     String commandDir = GetApplicationDirectory(3, 0); 
     String restoreCommand = commandDir.PathConcatenate("RestoreDM"); 
     LaunchExternalProcessAsync(restoreCommand); 
     Sleep(0.1); 

     Object dialog = Alloc(UIFrame).Init(dialogSpec); 
     String result = (dialog.Pose()) ? "OK" : "Cancel"; 
     OKDialog(result); 
    } 
} 

void main() 
{ 
    Alloc(DeferredAlertTask); 
} 

main(); 

繰延警告タスクが上と呼ばれているので、非同期バリアントを使用する必要があるLaunchExternalProcessAsync()したがって、RestoreDMプログラムによってプロンプトが出されたときに、DMがウィンドウを復元するのをブロックします(DMがハングする)。カスタムダイアログが表示される前にDMアプリケーションウィンドウが復元されるようにするには、外部プログラムを呼び出した後に短いスリープが必要であることにも注意してください。

+0

私が心に留めていたほとんどの解決策。 (私は、cmd.exe経由で余分な実行可能ファイルがないことを期待していましたが、自分自身を見つけることができませんでした)info:GMS3には、DMアプリケーションウィンドウを最小化/復元するコマンドがあります。私はあなたが与えた理由を正確に推測します... – BmyGuest

関連する問題