Sign in to follow this  
Followers 0
Lynie

GDI in other handle

15 posts in this topic

#1 ·  Posted (edited)

Is it possible to use GDI to draw something in another handle then your program's handle?

Thanks

Edited by Lynie

Share this post


Link to post
Share on other sites



Yes. I've painted in windows that don't belong to my program before.

Share this post


Link to post
Share on other sites

Quick 'n' dirty example:

#include <GDIPlus.au3>
;Run program
$iPID = Run("Notepad")
;Wait for it to become active
Sleep (500)
;get the window handle
$hWnd = _GetHwndFromPID($iPID)
;get the control handle
$hControl = ControlGetHandle($hWnd, "", "[CLASS:Edit; INSTANCE:1]")
;start GDI  and draw the string
_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hControl)
$hBrush = _GDIPlus_BrushCreateSolid(0x7F00007F)
$hFormat = _GDIPlus_StringFormatCreate()
$hFamily = _GDIPlus_FontFamilyCreate("Arial")
$hFont = _GDIPlus_FontCreate($hFamily, 12, 2)
$tLayout = _GDIPlus_RectFCreate(140, 110, 100, 20)
_GDIPlus_GraphicsDrawStringEx($hGraphic, "Hello world", $hFont, $tLayout, $hFormat, $hBrush)

; Clean up resources
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
;Wait...
Sleep (4000)

;Function to convert PID to HWND
Func _GetHwndFromPID($PID)
    $hWnd = 0
    $winlist = WinList()
    Do
        For $i = 1 To $winlist[0][0]
            If $winlist[$i][0] <> "" Then
                $iPID2 = WinGetProcess($winlist[$i][1])
                If $iPID2 = $PID Then
                    $hWnd = $winlist[$i][1]
                    ExitLoop
                EndIf
            EndIf
        Next
    Until $hWnd <> 0
    Return $hWnd
EndFunc  ;==>_GetHwndFromPID

You will probably need to hook the window for the likes of repainting when certain actions such as resizing, repainting of the window occurs etc.

Cheers,

Brett

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thanks!

Edited by Lynie

Share this post


Link to post
Share on other sites

It worked fine with Notepad, but when I tried it with FreeCell it doesn't work.

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Well if I understand it correctly, the minute that window gets redrawn, the text will cease to be there, hence the need to hook the window.

Cheers,

Brett

Thanks for the reply. But I already thought about that I just redraw the line in a loop (while 1). But it doesn't work :s

Share this post


Link to post
Share on other sites

Did you check the handle to make sure it returned valid?

Share this post


Link to post
Share on other sites

Did you check the handle to make sure it returned valid?

Well it should since I just run it like BretF's example.

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

I have the script to do the same thing in C++. Exactly the same works fine with notepad, but doesn't work in FreeCell or any other process :s.

#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd,
                         UINT msg,
                         WPARAM wparam,
                         LPARAM lparam)
{
    switch(msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    }
    return DefWindowProc(hwnd, msg, wparam, lparam);
}

INT WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nShowCmd)
{
    WNDCLASSEX wc;
    MSG msg;
    HWND hwnd, hTarget;
    HDC hdc;

    ZeroMemory(&wc, sizeof(wc));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "BASIC";
    wc.lpszMenuName = NULL;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

    RegisterClassEx(&wc);

    hwnd = CreateWindowEx(NULL,
        "BASIC",
        "NoScope",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        200,
        200,
        250,
        300,
        NULL,
        NULL,
        hInstance,
        NULL);

    hTarget = FindWindow(NULL, "FreeCell");
    Sleep(500);
    hdc = GetDC(hTarget);

    if(!hTarget)
        return 1;
    if(!hdc)
        return 1;

    while(true)
    {
        Sleep(1);

        Rectangle(hdc, 5, 5, 20, 20);

        GetMessage(&msg, NULL, NULL, NULL);

        TranslateMessage(&msg);
        DispatchMessage(&msg);

        if(msg.message == WM_QUIT)
            break;
    }
}

EDIT: Works in wordpad too :)

Edited by Lynie

Share this post


Link to post
Share on other sites

Try alter the sleep time....

Thanks, I tried that and when I opened up counter strike I saw a rectangle for like 1 second. So I must be getting close(I guess)

Share this post


Link to post
Share on other sites

Like I said you need to hook the window to redraw it.

Could you give a small example on how to do that please?

Share this post


Link to post
Share on other sites

As tempting as it is to let you get banned from your game for modifying it, I'm closing this. You're not going to leech on users who are too silly to realize helping you is a waste of their time. As a result I'm closing this thread.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  
Followers 0