マウスを右クリックした直後か瞬間に右クリックは無関係か分からないですが左クリックとして見なす事は可能ですか?(Windows)

実現したいこと

質問失礼します。当方、ドット絵の
グラフィックソフトをソフトウェアでトレース(出来るか分からないですが)
したいソフトを作っています。
エラーはコンパイルエラーの途中はいいとして、ウィンドウが消えたり、ウィンドウ内で
マウスポインタがあまり動かずに固定されることです。なので何度もCtrl+Alt+Delで
ログオフしてエラーというかバグを回避している状況です。

で、マウスは右半分にマウスにある時か、左半分にある時で弄れればこのようなバグを回避出来ると
思いました。さらにShiftキーとマウスクリックとの同時判定のやり方がよく分からないですが、それが
可能ならShiftキー+右クリック、Shiftキー+左クリックは、スポイトと点の描画で、
普通のクリックは単にソフトの機能の操作にしたいのですが、こんなソフトウェアというのは
可能でしょうか?

今のところ、Edge(TAKABO-SOFT様)の設定をいじって、同時起動を可能にした後に
左右のウィンドウハンドル取得、MoveWindowで左右最大化に
成功しました。で、さきほどのバグに遭遇しました。

WinAPIやWindowsプログラミングとc言語に詳しい方にお聞きしますが、
どうすれば可能でしょうか?

発生している問題・分からないこと

具体的には、右クリックした直後に
SetFocusの後にSetCursorPosとmouse_eventを行うと、
マウスカーソルやウィンドウが制御できなくなります。

エラーメッセージ

error

1エラーメッセージは、無いですが、エラーはバグとして存在します。

該当のソースコード

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; POINTS pts; POINT pt; HWND hTarget2[2]={0};//[0]はソース、[1]は送信先 HWND hTarget; HDC hdc, hdc_mem; PAINTSTRUCT ps; HBITMAP hBit; BITMAP bmp_info; static int wx, wy; RECT rc; static POINT Mem_PntXY; static int RightDragFlag=0; switch (msg) { case WM_CREATE: SetCursor(LoadCursor(NULL, IDC_ARROW)); pts = MAKEPOINTS(lp); ScreenWidth = GetSystemMetrics(SM_CXSCREEN); ScreenHeight = GetSystemMetrics(SM_CYSCREEN); SetTimer(hWnd,100,1000/60,NULL); MoveWindow(hWnd,(ScreenWidth-800)/2,(ScreenHeight-180-30+5),800,165,TRUE); break; case WM_PAINT: if (!bCap) { GetClientRect(hWnd, &rc); hdc = BeginPaint(hWnd, &ps); hBit = LoadBitmap(hInst, "MYBMP"); GetObject(hBit, sizeof(BITMAP), &bmp_info); wx = bmp_info.bmWidth; wy = bmp_info.bmHeight; hdc_mem = CreateCompatibleDC(hdc); SelectObject(hdc_mem, hBit); BitBlt(hdc, (rc.right - wx)/2, (rc.bottom-wy)/2, wx, wy, hdc_mem, 0, 0, SRCCOPY); pts=MAKEPOINTS(lp); ShowPoint(hWnd,pts); DeleteDC(hdc_mem); DeleteObject(hBit); EndPaint(hWnd, &ps); } break; case WM_COMMAND: switch(LOWORD(wp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; } break; case WM_TIMER: if(GetAsyncKeyState(VK_SPACE)<0 && flagcounter==3) { flagcounter=5; pts=MAKEPOINTS(lp); ShowPoint(hWnd,pts); } if(GetAsyncKeyState(VK_LSHIFT)<0) { if(flagcounter==5 && RightDragFlag==1) { // RightDragFlag=0; // ウィンドウを最前面に SetForegroundWindow(hTarget2[0]); // フォーカスがあるウィンドウハンドルを取得 //GetFocus(); int MX=Mem_PntXY.x-ScreenWidth/2; int MY=Mem_PntXY.y; GetCursorPos(&Pnt); SetCursorPos(MX,MY); mouse_event(MOUSEEVENTF_LEFTDOWN,MX ,MY, 0, 0); //mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, MX, MY, 0, 0); } }else{ if(flagcounter==5) { // RightDragFlag=0; // ウィンドウを最前面に SetForegroundWindow(hTarget2[1]); // フォーカスがあるウィンドウハンドルを取得 //GetFocus(); int MX=Mem_PntXY.x-ScreenWidth/2; int MY=Mem_PntXY.y; SetCursorPos(MX,MY); mouse_event(MOUSEEVENTF_LEFTDOWN,MX ,MY, 0, 0); //mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, MX, MY, 0, 0); } } pts=MAKEPOINTS(lp); if(flagcounter==5 && RightDragFlag==1) { SetCursorPos(100,200); mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); //mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); //char str[100]; //sprintf(str,"X=%d:Y=%d",Mem_PntXY.x,Mem_PntXY.y); //TextOut(GetDC(hWnd),0,0,str,strlen(str)); } InvalidateRect(hWnd,NULL,TRUE); break; case WM_LBUTTONDOWN://左クリックされたら { //if(flagcounter<3) { bCap = TRUE; SetCapture(hWnd); SetCursor(LoadCursor(hInst, "MYCURSOR")); pts = MAKEPOINTS(lp); ShowPoint(hWnd,pts); InvalidateRect(hWnd, NULL, TRUE); //MessageBox(hTarget2[1],"MOUSE CLICK EVENT OCCURED","OK?",MB_OK); } //if(flagcounter==4) //static int flag=0; break; } case WM_RBUTTONDOWN://右クリックされたら //if(GetAsyncKeyState(VK_RSHIFT)<0) { if(flagcounter==5){ GetCursorPos(&Mem_PntXY); } } break; case WM_RBUTTONUP: break; case WM_MOUSEMOVE: if(GetAsyncKeyState(VK_RBUTTON)<0) { RightDragFlag=1; }else{ RightDragFlag=0; } if (bCap) //&& flagcounter<3) { SetCursor(LoadCursor(hInst, "MYCURSOR")); pts = MAKEPOINTS(lp); ShowPoint(hWnd, pts); } else SetCursor(LoadCursor(NULL, IDC_ARROW)); break; case WM_LBUTTONUP: //if(flagcounter==4) // PostMessage(hTarget2[1],WM_LBUTTONUP,NULL,(MouseY<<8) | (MouseX-ScreenWidth/2)); //else { SetCursor(LoadCursor(NULL, IDC_ARROW)); pts = MAKEPOINTS(lp); pt.x = pts.x; pt.y = pts.y; ClientToScreen(hWnd, &pt); hTarget = WindowFromPoint(pt); } if (hTarget == NULL || hTarget==hWnd) { // MessageBox(hWnd, "失敗です", "失敗", MB_OK); //return (DefWindowProc(hWnd, msg, wp, lp)); }else if(hTarget!=NULL && hTarget!=hWnd && flagcounter<4){ if(flagcounter==0) { hTarget2[0]=hTarget; flagcounter=1; } else if(flagcounter==1) { hTarget2[1]=hTarget; flagcounter=2; } if(flagcounter==1) { SetWindowText(hTarget2[0], "ソースウィンドウ"); MoveWindow( hTarget2[0], // ウィンドウのハンドル ScreenWidth/2, // 横方向の位置 0, // 縦方向の位置 ScreenWidth/2, // 幅 ScreenHeight-200, // 高さ TRUE // 再描画オプション ); //flagcounter=1; } else if(flagcounter==2) { SetWindowText(hTarget2[1], "送信先ウィンドウ"); flagcounter=3; MoveWindow( hTarget2[1], // ウィンドウのハンドル 0, // 横方向の位置 0, // 縦方向の位置 ScreenWidth/2, // 幅 ScreenHeight-200, // 高さ TRUE // 再描画オプション ); } char str[100]; sprintf(str,"flagcounter=%d",flagcounter); TextOut(GetDC(hWnd),0,100,str,strlen(str)); } //if(flagcounter==5) { ReleaseCapture(); bCap = FALSE; } InvalidateRect(hWnd, NULL, TRUE); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }

試したこと・調べたこと

上記の詳細・結果

case WM_RBUTTONDOWN://右クリックされたら

//if(GetAsyncKeyState(VK_RSHIFT)<0) { if(flagcounter==5){ GetCursorPos(&Mem_PntXY); if(flagcounter==5) { // RightDragFlag=0; // ウィンドウを最前面に SetForegroundWindow(hTarget2[0]); // フォーカスがあるウィンドウハンドルを取得 GetFocus(); int MX=Mem_PntXY.x-ScreenWidth/2; int MY=Mem_PntXY.y; GetCursorPos(&Pnt); SetCursorPos(MX,MY); mouse_event(MOUSEEVENTF_LEFTDOWN,MX ,MY, 0, 0); //mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, MX, MY, 0, 0); } } }

ここで入力するためにソースを弄ったので合っているかは分からないですので勘でものを言うのですが
失礼します。)
上のようにソースをいじるとマウスカーソルが恐らく左ウィンドウで固まるか、
あるいは、左右のウィンドウが画面上から消えます。

補足

Windows11 home,Memory16GB,VisualC++2008

コメントを投稿

0 コメント