From: Paul N on 26 Jan 2010 17:49 I'm trying to write a program to give the colour values of a point on the screen. (I think this sort of tool is called an eye-dropper.) My program is based in the Blowup program in Petzold, and I've included the interesting bits below. What is supposed to happen is that, to start it going, you click within the client area. This captures the mouse. Then, if you click outside the client area, the window shows the values for the point that you clicked on. Clicking within the client area un-captures the mouse and so puts things back to normal. Most of it works. Clicking within the client area does appear to capture the mouse; clicking in the client area again un-captures it again. And, when it is captured, the first time you click outside the client area, it does seem to give the values for this point. But clicking a second time outside the client area doesn't seem to work. It's as if the first click loses the capture. Am I doing something wrong? Also, Petzold sems to suggest that the mouse cursor can be set for when it is captured. But in my program, although I get the cross-hairs cursor within the client area, it turns to a different cursor (depending on what it is passing over) as soon as it leaves my program's window - even before the first click, while it is presumably properly captured. Am I doing something wrong, or mis-understanding something? Thanks for any help. Paul. void write(HDC hdc, int x, int y, LPCTSTR str) { TextOut(hdc, x, y, str, lstrlen(str)); } void repaint(HWND hWnd) { InvalidateRect(hWnd, NULL, TRUE); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; static int capture, result; static TCHAR buff[30]; static POINTS pts; static POINT p; static RECT rect; static COLORREF col; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_CREATE: capture = FALSE; result = FALSE; break; case WM_LBUTTONDOWN: if (!capture) { capture = TRUE; SetCapture(hWnd); SetCursor(LoadCursor(NULL, IDC_CROSS)); repaint(hWnd); } else { pts = MAKEPOINTS(lParam); POINTSTOPOINT(p, pts); GetClientRect(hWnd, &rect); if (PtInRect(&rect, p)) { capture = FALSE; result = FALSE; ReleaseCapture(); repaint(hWnd); } else { result = TRUE; hdc = CreateDC(_TEXT("DISPLAY"), NULL, NULL, NULL); ClientToScreen(hWnd, &p); col = GetPixel(hdc, p.x, p.y); _stprintf(buff, _TEXT("Result: R %d, G%d, B %d"), GetRValue(col), GetGValue(col), GetBValue(col)); DeleteDC(hdc); repaint(hWnd); } } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... if (!capture) write(hdc, 0, 0, _TEXT("Click in window to begin capture")); else { write(hdc, 0, 0, _TEXT("Captured - click outside window to test point")); write(hdc, 0, 20, _TEXT("Click inside window to end capture")); } if (result) write(hdc, 0, 60, buff); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
From: Seetharam on 26 Jan 2010 18:13 Try handling WM_CAPTURECHANGED and see the value of lParam( the window that is taking teh capture away ). That way you would know what is actually happening once you click outside your client area. -Seetharam
From: Paul N on 27 Jan 2010 17:03 On 26 Jan, 23:13, Seetharam <smi...(a)gmail.com> wrote: > Try handling WM_CAPTURECHANGED and see the value of lParam( the > window that is taking teh capture away ). That way you would know what > is actually happening once you click outside your client area. I haven't tried exactly doing that, as I don't know the handles of any of the other windows anyway. But I've tried a few things and it seems that, with my original code, the capture is lost just after the mouseclick message - before the repaint message. I've tried adding the following: case WM_CAPTURECHANGED: if (capture) { SetForegroundWindow(hWnd); SetCapture(hWnd); } break; and it works a bit better, but it's still not reliable, and I don't see why I need to do it anyway.
|
Pages: 1 Prev: U++ 1952 released Next: Has everybody gone over to C#, or still at C/C++ ? |