- ベストアンサー
別ウインドウのハンドル取得の方法
SDKで親ウィンドウを作ると同時に、OpenCVというコンピュータービジョンのライブラリを用いて、別のウィンドウを作りそこにある画像を表示させました。 このライブラリの関数を用いて作ったウィンドウの画像について、マウスの座標位置を取得したいのですが、この場合ウィンドウハンドルはどのように取得したらよいのでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
hPhotoを取得しただけで何もしていないように見えますが。 プロシージャを自作のものに置き換えたいのであればSetWindowLongで新しいプロシージャへのポインタを送らないといけないですが、省略しただけなのでしょうか。 このままではPhotoProcは作られだけで、一切処理されていません。 PhotoProcにあるWM_CREATEもSetWindowLongで置きかえる頃にはとっくに別のプロシージャで処理済みなので、実行されないコードですね。 > DefWindowProc(hPhoto, msg, wp, lp) もCallWindowProcにしてください。 OpenCVが持っているプロシージャを置き換えるのですから、OpenCVのプロシージャに戻さないと変な動作をするようになるはずです。 マウス関連のメッセージを自分で処理したいだけであれば、cvSetMouseCallbackの方が簡単かもしれません。 WM_MOUSEMOVE、WM_?BUTTONDOWN/UP/DBLCLKがcvSetMouseCallbackで指定した関数に送られてくる(名前は変わってますが)ようになります。 CV_EXTERN_C_FUNCPTR( void (*CvMouseCallback )(int event, int x, int y, int flags) ); HIGHGUI_API void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse ); イメージとしてはこんな感じですね。実際は色々と違いますけど。 on_mouse(msg, LOWORD(lParam), HIWORD(lParam), wParam); ライブラリ等を使う場合は、HWNDやポインタが取得できるからと言って、むやみに使用してしまうとライブラリ自体の誤動作を招きかねないので、できるだけライブラリが提供している関数群を使うようにしたほうがいいです。
その他の回答 (3)
- hofuhofu
- ベストアンサー率70% (336/476)
cvNamedWindowで付けた名前をcvGetWindowHandleに渡して、返り値をHWNDにキャストしたらできないでしょうか。
補足
回答の通りやってみましたが、ウインドウにマウス座標が表示されません。どこが悪いのでしょうか?プログラムを載せますのでタイヘンだとは思いますがお願いいます。 #include <cv.h> #include <highgui.h> #include <windows.h> #include <string.h> #include <stdio.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK PhotoProc(HWND,UINT,WPARAM,LPARAM); void ShowPoint(HWND,POINTS); char szClassNme[] = "WinName"; BOOL bCap = FALSE; IplImage *image; FILE *fp; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hWnd; MSG msg; WNDCLASS myProg; if (!hPreInst) { myProg.style =CS_HREDRAW | CS_VREDRAW; myProg.lpfnWndProc =WndProc; myProg.cbClsExtra =0; myProg.cbWndExtra =0; myProg.hInstance =hInstance; myProg.hIcon =NULL; myProg.hCursor =LoadCursor(NULL, IDC_ARROW); myProg.hbrBackground =(HBRUSH)(COLOR_WINDOW+1);//GetStockObject(WHITE_BRUSH); myProg.lpszMenuName =NULL; myProg.lpszClassName =szClassNme; if (!RegisterClass(&myProg)) return FALSE; } hWnd = CreateWindow(szClassNme, "CVWINDOW", WS_OVERLAPPEDWINDOW, 600, 400, 100, 100, 0, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (0); } //********メインウィンドウプロシージャ*********** LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HWND hPhoto; switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: fp = fopen("image1.png", "rb"); if(!fp){ fprintf(stderr,"Unable to open file \n"); exit(1); } image = cvLoadImage( "image1.png", 3); cvNamedWindow("cam", CV_WINDOW_AUTOSIZE); cvShowImage("cam",image); hPhoto = (HWND)cvGetWindowHandle("cam"); return (0); case WM_KEYDOWN: if(wParam == VK_ESCAPE){ PostMessage(hWnd, WM_CLOSE, 0, 0); } return(0); case WM_CLOSE: DestroyWindow(hWnd); return(0); default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0); } //************photoウィンドウプロシージャ***************** LRESULT CALLBACK PhotoProc(HWND hPhoto, UINT msg, WPARAM wp, LPARAM lp) { POINTS pts; switch (msg) { case WM_LBUTTONDOWN: bCap = TRUE; SetCapture(hPhoto); pts = MAKEPOINTS(lp); ShowPoint(hPhoto, pts); break; case WM_MOUSEMOVE: if (bCap) { SetCursor(LoadCursor(NULL, IDC_CROSS)); pts = MAKEPOINTS(lp); ShowPoint(hPhoto, pts); } else SetCursor(LoadCursor(NULL, IDC_ARROW)); break; case WM_LBUTTONUP: SetCursor(LoadCursor(NULL, IDC_ARROW)); ReleaseCapture(); bCap = FALSE; break; case WM_CREATE: SetCursor(LoadCursor(NULL, IDC_ARROW)); break; case WM_CLOSE: DestroyWindow(hPhoto); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hPhoto, msg, wp, lp)); } return 0L; } void ShowPoint(HWND hPhoto, POINTS pt) { char str[256]; char *sp = " "; HDC hdc; wsprintf(str, "x = %3d, y = %3d", pt.x, pt.y); hdc = GetDC(hPhoto); TextOut(hdc, 20, 20, sp, strlen(sp)); TextOut(hdc, 20, 20, str, strlen(str)); ReleaseDC(hPhoto, hdc); return; }
- SpiralGalaxy
- ベストアンサー率39% (649/1653)
基本は FindWindow() でしょうが該当ウインドウのクライアント領域が実は子ウインドウだったりする場合もあるのでマウス座標変換するなら、FindowWindowEx() をさらに使わないとならない場合もあるでしょう。 スパイを使ってそれを確かめてみてください。 他にも EnumWindows() なんてのもありますよ。
お礼
ありがとうございました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
キャプション名、またはウィンドウクラス名がわかっているのであれば、FindWindow()。 ウィンドウの座標がわかっているのであれば、WindowFromPoint()。 ってところでいいのかな?
お礼
ありがとうございました。
お礼
とても詳しいご説明感謝しております。 回答を参考に試行錯誤してみたいと思います。 また質問をするかもしれませんが、そのときはよろしくお願いします。 ほんとうにありがとうございました。