Spy Action-Form Detector
Recently, I am deeply interested in SPY, I am ready to conduct a spy action, the goal is simple, using the enableWindow function to activate the unavailable or invalid control button, of course, this form detector is essential, it is very simple, But actually act, but I have encountered a lot of trouble, and will now be recorded for interest in interest.
We have seen the form detector in Spyxx. When the mouse is pressed on the form detector, change the mouse style while capturing mouse, detect the form under the mouse until the left mouse button is released. This way we can write the code frame:
Case WM_LBUTTONDOWN: / / The left mouse button is pressed, detect drag or detection
{
MSG msg;
/ / Press the mouse in the form detector
IF (== True in the form detector) // Replace the cursor, detect drag
{
/ / Change the mouse style
SetCursor (...);
// capture mouse
SetCapture (hwnd);
HWNDNOW = NULL; // The current form is set to empty // This is a global variable
/ / Get mouse movement message
While (GetMessage (& MSG, NULL, WM_MOUSEFIRST, WM_MOUSELAST))
{
IF ((Msg.Message == WM_Mousemove) || (msg.Message == WM_NCMOMOVE))
{
HWND HWNDPOINT;
// Set the cursor
SetCursor (LoadCursor (Hinst, (LPCTSTR) CUR_WINDOWSPY);
GetCursorpos (& POIN);
// Detect the current mouse point
IF (hwndpoint = windowfrompoint (point))
{
IF (hwndnow! = hwndpoint) // target has changed
{
IF (HWNDNOW)
{
/ / Clear the black box on the old goal
XORBORDER (HWNDNOW);
}
/ / And do not belong to this thread
IF (HWNDOWTHREADPROCESSID (HWNDPOINT, NULL)! = getCurrentThreadId ())
{
// Painting the current form a black border
HWNDNOW = hwndpoint;
XORBORDER (HWNDNOW);
}
Else
{
HWNDNOW = NULL;
}
// Display Form Information
ShowWindowMessage (HWND, HWNDNOW);
}
}
Else
{
HWNDNOW = NULL;
ShowWindowMessage (HWND, HWNDNOW);
}
}
// If the left button is loose, jump out
Else if (msg.message == wm_lbuttonup)
{
Break;
}
}
XORBORDER (HWNDNOW);
/ / Release the mouse and restore mouse styles
SetCURSOR (LoadCursor (NULL, (LPCTSTR) IDC_ARROW);
Releasecapture ();
}
Break;
}
The problem here is
WindowFromPoint and
XORBORDER. Here we look at the first edition first
XORBORDER:
Void Xorborder (HWND HWND)
{
Rect Rect; // Current Form area
HDC HDC = GetWindowDC (HWND);
GetWindowRect (hwnd, & review);
// Adjust the border
Rect.bottom- = Rect.top;
Rect.right- = Rect.Left;
Rect.Left = Rect.top = 0;
SETROP2 (HDC, R2_NOT); FrameRect (HDC, & Rect, getStockObject (Black_brush));
ReleaseDC (HWND, HDC);
}
However, the result is always failed to end, view setrop2 information, and faintly feel that it only works on the brush, the painting brush is invalid (only represents personal point of view, is wrong). So change it to Rectangle, but it is even more within the frame with the rectangle, which is not what I want, what should I do? See my final solution:
Void Xorborder (HWND HWND)
{
HPEN HPEN, HOLDPEN;
Rect Rect; // Current Form area
HDC HDC = GetWindowDC (HWND);
GetWindowRect (hwnd, & review);
// Adjust the border
Rect.bottom- = Rect.top;
Rect.right- = Rect.Left;
Rect.Left = Rect.top = 0;
SETROP2 (HDC, R2_NOT);
HPEN = CREATEPEN (PS_SOLID, 6, RGB (0, 0, 0));
Holdpen = SELECTOBJECT (HDC, HPEN);
// Select the brush as empty, make the rectangle not fill the interior
SelectObject (HDC, getStockObject (null_brush));
Rectangle (HDC, Rect.Lect, Rect.top, Rect.right, Rect.bottom);
SelectObject (HDC, HoldPen);
DeleteObject (HPEN);
ReleaseDC (HWND, HDC);
}
I will choose the current painting brush, I don't know if this method is orthodox, anyway, MSDN is not found, although it is just a small change, I have a good job, I have been playing on frameerect!
Now let's look at the WindowFromPoint: MSDN say that the function skips the invalid button, you need to use childwindowFromPoint to solve, however, the problem is not so simple, first look at the following resource files:
IDD_DIALOG1 DIALOGEX 0, 0, 186, 110
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
Caption "Dialog"
Font 8, "MS Shell DLG", 400, 0, 0x1
Begin
Groupbox "Static", IDC_STATIC, 45, 14, 81, 69
Control "Select 1", IDC_CHECK1, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
57, 28, 61, 16
Control "Select 1", IDC_CHECK2, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
57, 54, 60, 10
End
I tried, I want to get IDC_CHECK1, IDC_CHECK2, use the above two functions that cannot be implemented, (Do you know, groupbox is the Button class, not static, until today I know), please don't tell me to change the groupbox Tab. Key order, our probe should face all kinds of situations, look at my solution: hWnd BrotherWindowFromPoint (HWND HWNDPOINT, CONST POINT)
{
// Test the brothers window
RECT RCPOINT;
Rect rcnow;
HWND HWNDBROTHER = HWNDPOINT; // getWindow (hwndpoint, gw_hwndfirst);
HWndPoint = NULL;
DO
{
IF (GetWindowStyle (HWNDBROTHER) & WS_Visible) // visible
{
GetWindowRect (hwndbrother, & rcnow);
IF (PtinRect (& RCNOW, POINT))
{
// Test the rectangular nested situation
IF (hwndpoint == null)
{
Hwndpoint = hwndbrother;
Rcpoint = rcnow;
}
ELSE IF
(RcNow.Bottom || ((rcnow.bottom || ((rcnow.top> rcpoint.top) && (rcnow.top || ((rcnow.top> rcpoint.top) && (rcnow.top ) { Hwndpoint = hwndbrother; Rcpoint = rcnow; } } } } while (hwndbrother = getWindow (hwndbrother, gw_hwndnext); Return hwndpoint; } This function detects the same level window, gets the deepest window in the specified point, where we can generate our own WindowFromPoint HWnd MyWindowFromPoint (const point point) { HWND HWNDPOINT = WindowFromPoint (POINT); IF (HWNDPOIN) { // Width Search Brothers HWND HWNDCHILD; IF (! (GetWindowlong (HWndPoint, GWL_Style) & WS_CHILD)) // Top window Return hwndpoint; // Non-top window, to find a brother. HWndPoint = MybrotherWindowFromPoint (hwndpoint, point); assert (hwndpoint); // Depth search sub-window While (hwndchild = gettopWindow (hwndpoint)) { // Width Search brother disciples window IF (null == (hWndChild = mybrotherwindowfrompoint (hwndchild, point)))) Break; Hwndpoint = hwndchild; } // * / } Return hwndpoint; } This function first determines if it is a top-level form, if not, first in the width search, although it is trouble, but it has to be true. By the way, the dialog that is being designed in the VC resource editor has a Disable property. SPYXX Your form probe does not get all the control handles in it, and the function is invincible, if you remove the visibility of the BrotherWindowFromPoint function, The hidden form is not hidden. Interested friends can design it, if you are lazy, you can go to the Huajun Software in the red spy. Personal Homepage: http://gg82.126.com