- ベストアンサー
CreateProcessでEXEを起動させると残像が残る
お世話になります。 VC++ 6.0 MFC で開発しております。 A.exeから、B.exeを起動しています。 A.exeの(画面上の)上にB.exeが表示されるのですが、 そのB.exeを動かすと白い残像みたいな跡がでます。 そのB.exeの残像みたいなのを出さないようにしたいのですがどのようにすればよいでしょうか ※B.exeを起動している間は、A.exeを操作できないようにしたいのです。 ***********実際のソースです。******** PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory(&si,sizeof(si)); si.cb=sizeof(si); int kekka = CreateProcess(Pass,CommandChar,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); if(kekka==0) { CString str; str.Format("起動することはできません。); AfxMessageBox(str, MB_OK, 0); } else { WaitForSingleObject(pi.hProcess,INFINITE); } PeekMessage()とかを使えばいいとか聞いたのですが、まったくわからない状態です。 大変お手数ですが具体的に教えていただければ大変ありがたいです。 なにとぞよろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
B.exeの終了を待たなければ、画面も正常に更新されます。 操作を禁止したいのなら、EnableWindowを使いましょう。 もちろん、このままではB.exeが終了してからもA.exeが操作不能のままなので、タイマーなどを使ってB.exeの終了を監視するといいでしょう。
その他の回答 (2)
- machongola
- ベストアンサー率60% (434/720)
こんにちは。 「B.EXEの終了を待機する」のではなく、「B.EXEの終了を通知してもらう」方が良いのでは。 其れにはスレッドを回して、B.EXEが終了した時、終了を通知する為のメンバ関数を呼び出してもらいます。 以下はボタン1を押してB.EXE(メモ帳)を立ち上げ、B.EXEが終了するまでダイアログが操作を受け付けないようにします。参考程度に。 //ヘッダ ///////////////////////////////////////////////////////////////////////////// // CMfcprocDlg ダイアログ class CMfcprocDlg : public CDialog { //省略 //追加分 //スレッド関数 static UINT ThreadProc(LPVOID pParam); //B.EXEが終了した時に呼ばれる void Done(); //アクセサ void SetProcess(HANDLE hProcess); HANDLE GetProcess(); protected: //クリティカルセクションクラス(stdafx.hの中にafxmt.hをインクルードしておく) CCriticalSection m_cs; //スレッドクラス CWinThread* m_pThread; //B.EXEのプロセスハンドル HANDLE m_hProcess; //省略 }; //ソース ///////////////////////////////////////////////////////////////////////////// // CMfcprocDlg ダイアログ CMfcprocDlg::CMfcprocDlg(CWnd* pParent /*=NULL*/) : CDialog(CMfcprocDlg::IDD, pParent), m_pThread(NULL),//初期化 m_hProcess(NULL)//初期化 { //省略 } //スレッド関数 UINT CMfcprocDlg::ThreadProc(LPVOID pParam) { CMfcprocDlg* pThis = static_cast<CMfcprocDlg*>(pParam); while(pThis->GetProcess()) { const DWORD dwResult = ::WaitForSingleObject(pThis->GetProcess(), 0); if(dwResult == WAIT_OBJECT_0 || dwResult == WAIT_ABANDONED_0) { //B.EXEのプロセスが終了したら呼び出す pThis->Done(); //スレッドから抜け出す break; } else if(dwResult == WAIT_TIMEOUT) { } ::Sleep(1); } //::MessageBox(NULL, TEXT("スレッド終了"), TEXT("確認"), MB_OK); return 0; } //ボタン1が押された時 void CMfcprocDlg::OnButton1() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください PROCESS_INFORMATION pi; STARTUPINFO si = {sizeof(si)}; //B.EXE(メモ帳)を立ち上げる const int kekka = ::CreateProcess(TEXT("c:\\winnt\\notepad.exe"), NULL, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); if(kekka==0) { CString str; str.Format(TEXT("起動することはできません。")); AfxMessageBox(str, MB_OK, 0); return; } //ウィンドウを無効化する this->EnableWindow(FALSE); //B.EXEのプロセスハンドルを設定する SetProcess(pi.hProcess); //スレッドを回す m_pThread = ::AfxBeginThread(&CMfcprocDlg::ThreadProc, this, 0, 0, CREATE_SUSPENDED, NULL); m_pThread->m_bAutoDelete = TRUE; m_pThread->ResumeThread(); } //B.EXEが終了した時 void CMfcprocDlg::Done() { //::AfxMessageBox(TEXT("待機完了"), MB_OK, 0); //ウィンドウを有効化する this->EnableWindow(TRUE); this->SetActiveWindow(); //プロセスハンドルの設定をクリアする SetProcess(NULL); m_pThread = NULL; } //プロセスハンドルを設定する void CMfcprocDlg::SetProcess(HANDLE hProcess) { m_cs.Lock(); m_hProcess = hProcess; m_cs.Unlock(); } //設定したプロセスハンドルを取り出す HANDLE CMfcprocDlg::GetProcess() { m_cs.Lock(); HANDLE hProcess = m_hProcess; m_cs.Unlock(); return hProcess; }
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
WaitForSingleObject(pi.hProcess,INFINITE); により「起動したプロセスがシグナル状態になる(つまり、B.exeが終了する)まで、何もしない」と言う処理をしている為「A.exeが再描画メッセージを受け取っても、再描画を行わない(「何もしない」のだから再描画さえしないのは当然)」のが「跡が残る原因」です。 >※B.exeを起動している間は、A.exeを操作できないようにしたいのです。 ・メッセージを処理しないから、A.exeを操作できない ・メッセージを処理しないから、A.exeが再描画をせず跡が残る 上記の2つは相反します。 ・メッセージを処理すると、A.exeが操作できてしまう ・メッセージを処理すると、A.exeが再描画され跡が残らない 上記の2つも相反します。 そういう訳で「簡単には解決しない」でしょう。