Jump to content
Sign in to follow this  
Lynie

GDI in other handle

Recommended Posts

Lynie

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
Richard Robertson

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

Share this post


Link to post
Share on other sites
BrettF

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
Lynie

Thanks!

Edited by Lynie

Share this post


Link to post
Share on other sites
Lynie

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
BrettF

Share this post


Link to post
Share on other sites
Lynie

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
Richard Robertson

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

Share this post


Link to post
Share on other sites
Lynie

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
BrettF
Lynie

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
Lynie

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
BrettF
Lynie

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
Valik

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.