• ベストアンサー

アプリがフォーカスを

自分のWindowから他のアプリのWindowに 移す事は可能でしょうか? 仕様上不可能なのでしょうか? 可能だとすれば 自アプリのWindowをhWmineとし 他アプリのWindowをhWotherとしたとき どのようにすればいいのでしょうか? ちなみに DWORD dw_other=GetWindowThreadProcessId(hWother,NULL); DWORD dw_mine=GetWindowThreadProcessId(hWmine,NULL); AttachThreadInput(dw_mine,dw_other,TRUE); ShowWindow(hWother,SW_SHOWMAXIMIZED); SetForegroundWindow(hWother); AttachThreadInput(dw_other,dw_mine,FALSE); とするとすぐに一瞬他Windowにフォーカスが移りすぐに自Windowにフォーカスが戻ってきます 最後の AttachThreadInput(dw_other,dw_mine,FALSE); をはずしても同じでした

  • keyguy
  • お礼率68% (895/1314)

質問者が選んだベストアンサー

  • ベストアンサー
  • kmb01
  • ベストアンサー率45% (63/138)
回答No.4

他のウィンドウにフォーカスを移すには本来SetForegroundWindowだけで十分のはずで、 それで移動しない、戻ってくるのは余計な処理をしているからとしか考えられません。 そもそもShellExecuteで起動すればそれが最前面にくるはずです。

keyguy
質問者

お礼

ありがとうございます 余計な事をしているみたいなので調べてみます

その他の回答 (3)

回答No.3

HWND SetForegroundWindowEx(HWND hWnd) { // 強制的に Foreground にする HWND hWndOrg = ::GetForegroundWindow(); DWORD dwID= ::GetWindowThreadProcessId(hWndOrg, NULL); AttachThreadInput(::GetCurrentThreadId(), dwID, TRUE); ::SetForegroundWindow(hWnd); AttachThreadInput(::GetCurrentThreadId(), dwID, FALSE); return hWndOrg; } の引数 hwnd を他のアプリのウィンドウズハンドルにすればいいと思います。

keyguy
質問者

補足

ありがとうございます 前面に出したいhtmlのWindowはhWhtmlとし 前面に出ているのは自アプリのWindowでWmainとしたときに DWORD dw_html=GetWindowThreadProcessId(hWhtml,NULL); DWORD dw_main=GetWindowThreadProcessId(hWmain,NULL); AttachThreadInput(dw_main,dw_html,TRUE); SetForegroundWindow(hW); AttachThreadInput(dw_html,dw_main,FALSE); を実行しても一瞬フォーカスがhtmlにいくのですが すぐに自アプリに戻ってきます

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>ShellExecute(NULL,"open","mywindow.html",NULL,NULL,SW_SHOWMAXIMIZED); 起動直後だと早すぎるのかも。 WaitForInputIdleで起動したIEが入力待ちになるまで待ってみるとか。 >Sleep(1000); 1秒じゃ足りないのかも・・・ WaitForInputIdle()で試す前に1分くらい待ってみたらどうなります? あと、Sleepじゃなくてちゃんとタイマー作ってみるとか。

keyguy
質問者

補足

ありがとうございます 60秒でやってみると60秒たつまで HTMLが前面に出てしかもフォーカスされています しかし60秒後自アプリが起きてきてフォーカスを奪い取ります だから ShellExecute(NULL,"open",str1.c_str(),NULL,NULL,SW_SHOWMAXIMIZED); だけで希望の処理はできているけれどもその後 自アプリがフォーカスを奪うのが問題のようです 自アプリが寝たままだと困りますがおきたときにフォーカスを取らなければ問題はないようです

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

>あとは、ボタンを押してってことなんで、ボタンのクリック時には処理をせずに、PostMessageで自分宛に >独自メッセージをポストし、ポストしたメッセージを受け取ってから他アプリの最前面化をしてみるのも効果があるかも。 これどうなりますかねぇ? もしくはタイマーでボタンを押してから1秒後ぐらいに処理させてみるとか。 単にボタンを押して、その後ボタンを戻す処理をWindowsがするから自ウィンドウにフォーカスが戻ってくるような気がするんですけど。

keyguy
質問者

補足

ありがとうございます サブを BOOL CALLBACK EnumProc(HWND hW,LPARAM) { char s[999]; SendMessage(hW,WM_GETTEXT,999,(LPARAM)s); if(string(s).find("MyWindow")!=string::npos) { ShowWindow(hW,SW_SHOWMAXIMIZED); DWORD dw_html=GetWindowThreadProcessId(hW,NULL); DWORD dw_main=GetWindowThreadProcessId(hWmain,NULL); AttachThreadInput(dw_main,dw_html,TRUE); SetForegroundWindow(hW); AttachThreadInput(dw_html,dw_main,FALSE); return FALSE; } とし メインのボタン処理場所を ofs.open("mywindow.html"); ofs<<"<title>MyWindow</title>"<<endl; ofs.close(); ShellExecute(NULL,"open","mywindow.html",NULL,NULL,SW_SHOWMAXIMIZED); b_out=true; とだけし WinMainのお決まりの処理を while(GetMessage(&ms,NULL,NULL,NULL)) { TranslateMessage(&ms); DispatchMessage(&ms); if(b_out==true) { Sleep(1000); EnumWindows(&EnumProc,NULL); b_out=false; } } としましたがしっかりフォーカスが自分に戻ってきます 絶対にフォーカスを戻すんだという意気込みが感じられます 勿論自Windowを最小化するときれいにFocusがうつってくれます

関連するQ&A

  • C言語APIウィンドウズアプリにおいて

    他アプリのウィンドウにフォーカスがあるとき自アプリが作ったウィンドウにフォーカスを遷すために SetFocus(hW), SetActiveWindow(hW), SetForegroundWindow(hW) を使ったのですがどうもうまくいきません 他アプリのウィンドウにフォーカスがあるとき自アプリが作ったウィンドウにフォーカスを遷す方法か関数を教えてください

  • 2重軌道防止のサイトの説明

    に従って以下のようにしましたが 2重起動を発見してやめるために return false; としていますが return true; としたり booleanをやめて return int(0) とするとどうなるのでしょうか? WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { WNDCLASS wc; HWND hW,hPW; MSG ms; unsigned pos; HANDLE hMutex; hPW=FindWindow("goo","I am good."); hMutex=CreateMutex(NULL,TRUE,"UniqueName"); if(!hMutex)return FALSE; if (GetLastError()==ERROR_ALREADY_EXISTS) { ShowWindow(hPW,SW_RESTORE); SetForegroundWindow(hPW); return FALSE; } ・・・・・・・・・・・・・・・・・・・・

  • チャイルドダイアログボックスでマウスクリックが効かない

    チャイルドウィンドウタイプのモードレスダイアログを表示すると  マウスでエディットボックス(など)をクリックしてもフォーカスが移動しない という現象がおきています。(tabキーではOK) 数年前に一度作ったときの記憶を頼りに作っているのですが、下記以外に設定などが必要になるのでしょうか? …というか、このやり方で問題ないのでしょうか?… ◎環境 WindowsXP Visual C++ 6.0 & MFC アプリケーションの種類…SDI ◎やったこと 1.ダイアログリソースを追加 リソースのプロパティ  「一般」タブ   ID…「IDD_DIALOGA」  「スタイル」タブ   スタイル…チャイルド   境界線…ダイアログ枠   その他…すべてoff  「その他のスタイル」タブ   可視のみon  「拡張スタイル」、「その他の拡張スタイル」タブ   すべてoff  このダイアログにいくつかのボタンやエディットボックスを配置 2.親windowのヘッダファイルに追加したもの private: dialogA *pDlg; 3.親windowのソースファイルに追加したもの BOOL CModlessDialogApp::InitInstance() にコードを追加 …… // フレームをリソースからロードして作成します pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); //↓↓ここから追加↓↓ pDlg = NULL; pDlg = new dialogA(); if(pDlg) { pDlg->Create(IDD_DIALOGA); pDlg->ShowWindow(SW_SHOWNA /*SW_SHOW|SW_RESTORE*/); } //↑↑ここまで追加↑↑ // メイン ウィンドウが初期化されたので、表示と更新を行います。 pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); …… スタイルを「オーバーラップ」「ポップアップ」にするとマウスクリックでフォーカスが移動します。

  • 他のアプリの表示、非表示について

    他のアプリケーション(アプリA)をコントロールするプログラムを作っています。アプリAと自作アプリは起動したままです。自作アプリでボタンを押すとアプリAを表示させてアクティブにして仕事をさせ、終わったら非表示にします。 アプリAのハンドルをhandle = FindWindow()で取得して ShowWindow(handle,SW_SHOWNORMAL)で表示して、 ShowWindow(handle,SW_HIDE);で隠しています。 ボタンを押したときに、アプリAが表示されていると、非表示にしたあとタスクバーのアプリを手動で表示できません。 MINIMIZEやCloseWindos()も試しましたが、それだと画面の左下にアプリAが残ってしまいます。 SendMessage(handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);も試しましたがうまくいきません。使い方が悪いのかもしれません。 アプリAを隠す事と元のサイズで表示する。という二つの動作をプログラムで交互に行う場合に、途中で手動でアプリAの最小化、あるいはタスクバーから出すという動作をさせることができるのが希望です。どうすればよいでしょうか。 OSはXPです。

  • 次のWindowsアプリで

    メッセージボックスは他のアプリのWindowの下に隠れることはないのですが他のアプリのウィンドウをクリックするとメッセージボックスの焦点がぼけアクティブでなくなります メッセージボックスを常にアクティブにする方法を終えてください #include <windows.h> using namespace std; WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { HWND hW; hW=CreateWindow("STATIC","",WS_OVERLAPPED, 0,0,9,9,NULL,NULL,hI,NULL); SetWindowPos(hW,HWND_TOPMOST,0,0,9,9,NULL); MessageBox(hW,"OK?","",MB_OK); return 0; }

  • マルチスレッドプログラミングについて

    マルチスレッドプログラミングについていくつか教えて下さい。 マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。 1:イベントオブジェクトについて教えて下さい。 「イベントオブジェクト」の概念がよく分かりません。 ○シグナル状態と非シグナル状態とはどういう状態なのでしょうか? ○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合) ○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合) 2:CloseHandle() と ExitThread() について教えて下さい。 ○この2つの関数の役割の違いについて教えて下さい。 「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか? また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?) 下記のソースは簡略化のためかなり省略されています。 DWORD WINAPI ThreadProc( DWORD i ) { while( true ) { DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ); if( r == WAIT_OBJECT_0 ) { // 処理1 } else if( r == WAIT_OBJECT_0 ) { // 処理2 } else { ExitThread( TRUE ); // スレッド終了 } } } void MainProc() { // 自動リセットのイベントオブジェクト作成 for( int i=0; i<2; i++ ) { hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); } // スレッドを作成 hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID ); }

  • TABによるフォーカス移動

    実行環境: Microsoft Visual Studio 2005 質問: TABによるフォーカス移動が行えません。どのようにソースを変更すれば宜しいか教えてください。 以下ソース //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HINSTANCE main_inst; static HFONT main_hfont; main_inst = (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE ) ; static HWND hEdit1,hEdit2,hEdit3; switch (msg) { case WM_SETFOCUS: SetFocus(hEdit1); break; case WM_COMMAND: switch(LOWORD(wp)){ case ID_EDIT1: if(wp == VK_TAB) SetFocus(hEdit2); break; case ID_EDIT2: if(wp == VK_TAB) SetFocus(hEdit3); break; case ID_EDIT3: if(wp == VK_TAB) SetFocus(hEdit1); break; } case WM_CREATE: hEdit1 = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT("EDIT"),NULL,WS_CHILD|ES_NUMBER|WS_VISIBLE|ES_AUTOHSCROLL, 106, 89, 158, 34, hWnd, (HMENU)ID_EDIT1, main_inst, NULL ); hEdit2 = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT("EDIT"),NULL,WS_CHILD|ES_NUMBER|WS_VISIBLE|ES_NUMBER|ES_AUTOHSCROLL, 106, 143, 158, 34, hWnd, (HMENU)ID_EDIT2, main_inst, NULL ); hEdit3 = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT("EDIT"),NULL,WS_CHILD|ES_NUMBER|WS_VISIBLE|ES_AUTOHSCROLL, 106, 198, 158, 34, hWnd, (HMENU)ID_EDIT3, main_inst, NULL ); CreateWindow( TEXT("BUTTON"),TEXT("起動"),WS_CHILD|WS_VISIBLE|BS_MULTILINE|BS_CENTER, 89, 301, 112, 40, hWnd, (HMENU)ID_BUTTON, main_inst, NULL ); main_hfont = CreateFont( -19, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH|FF_MODERN, TEXT("MS ゴシック") ); SendDlgItemMessage( hWnd, ID_EDIT1, WM_SETFONT, (WPARAM)main_hfont, MAKELPARAM(TRUE, 0) ); SendDlgItemMessage( hWnd, ID_EDIT2, WM_SETFONT, (WPARAM)main_hfont, MAKELPARAM(TRUE, 0) ); SendDlgItemMessage( hWnd, ID_EDIT3, WM_SETFONT, (WPARAM)main_hfont, MAKELPARAM(TRUE, 0) ); SendDlgItemMessage( hWnd, ID_BUTTON, WM_SETFONT, (WPARAM)main_hfont, MAKELPARAM(TRUE, 0) ); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

  • カメラアプリの排他制御(android)

    はじめまして。android初心者の学生です。 androidでカメラアプリを作っていますが、エラーで落ちてしまいます。 端末はgalaxy note IIIです。 画面タッチでオートフォーカスを呼び出し、フォーカスが終わったらパシャリ。というシンプルなものなのですが・・・ 具体的には 「オートフォーカス最中に3回程タッチすると、たまにフリーズして落ちる」 といった状況です。そこで多重撮影を防止するため、排他制御とやらをしたいのですが・・・うまくいかず困っています。オートフォーカス中にタッチしても、オートフォーカスを呼び出さない・・・というところまでは作った(考えた)つもりです。が、恐らくおかしなソースになっていると思われます。 @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()&MotionEvent.ACTION_MASK){            case MotionEvent.ACTION_DOWN: if(mTouch==false) camera.autoFocus(this); break; case MotionEvent.ACTION_CANCEL: break; } return true; } public synchronized void onAutoFocus(boolean success, Camera camera) { mTouch = true; camera.autoFocus(mAutoFocusListener); } private Camera.AutoFocusCallback mAutoFocusListener = new Camera.AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { camera.takePicture(null, null, mPictureListener); } }; private Camera.PictureCallback mPictureListener = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { BitmapFactory.Options options = new BitmapFactory.Options(); Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length, options); MediaStore.Images.Media.insertImage(getContext().getContentResolver(), bmp, "", null); camera.startPreview(); mTouch = false; }; できるのなら一度画面に触れたら、タッチを無効にしたいです。 初歩的な問題だとは思いますが、ご指南いただけたらと思います。 よろしくお願いします。

  • スレッドについての質問です。

    下記のロジックを見ていただきたいのです。 スレッドがnullの間はrunが動いています。 問題は一番下に記載した"stopplay()"というメソッドだと思われます、スレッドを停止して直ぐにまた動かしていますがどうもスレッドが二つ動いている様子です。なぜでしょうか? ************************************************** //最初にスレッドを開始します。 public init(){ play(); } ************************************************** //スレッドのON OFF public void threadOnOff(boolean sw) { if(sw == true){ thread =new Thread(this); thread.start(); } else { thread = null; } } ************************************************** //スレッド開始 public void play(){ threadOnOff(true); } ************************************************** //スレッド停止 public void stop(){ threadOnOff(false); } ************************************************** //runメソッド  public void run(){ String mode = ""; while(thread != null){ try { thread.sleep(500); //0.5秒間隔で動きます。 mode = modeRequest(); if(mode.startsWith("STOP") == true) { //スレッド停止 threadOnOff(false); } } catch (InterruptedException ie) {} } } ************************************************** //問題のメソッドです。 public void stopplay(){ stop(); play(); }

    • ベストアンサー
    • Java
  • 再起動時、前起動分のハンドルを得る方法は?

    WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS) { WNDCLASS wc; HWND hW; MSG ms; //ここで前起動クローンのアプリやWindowのハンドルを取得したい wc.lpszClassName ="goo"; wc.lpfnWndProc =(WNDPROC)WinProcedure; wc.hInstance =hI; wc.style =CS_HREDRAW|CS_VREDRAW; wc.cbClsExtra =NULL; wc.cbWndExtra =NULL; wc.hIcon =LoadIcon(NULL,IDI_EXCLAMATION); wc.hCursor =LoadCursor(NULL,IDC_ARROW); wc.hbrBackground =(HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName =NULL; RegisterClass(&wc); hW=CreateWindow ( "goo", "教えてgoo!", WS_OVERLAPPED|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU, 0, 0, 640, 456, NULL, NULL, hI, NULL ); ShowWindow(hW,nCS); UpdateWindow(hW); while(GetMessage(&ms,NULL,NULL,NULL)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); } 上記アプリで//行で前起動時のWindowのハンドルを得るにはどうしたらいいのでしょうか?

専門家に質問してみよう