CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Dec 2006
    Posts
    203

    Drawing On Top Of Another Application

    I just created an application to see if I were able to draw a string on top of another application (a game). Essentially it's going to be a parser that will show how much damage you do per second, by reading a log file.

    What I'm currently doing is having a timer redraw it every so often, but problem is it flickers a lot. I remember when I created a screensaver I had to enable double buffering, to prevent it from flickering, but since I don't really have the same control over the application, I'm kinda stumped as to what to do. Here's the code I use to find window and draw on it:

    Code:
            Graphics eqGraphic;
            Font font;
            SolidBrush brush;
    
            private void Form1_Load(object sender, EventArgs e)
            {
                Process[] ps = Process.GetProcesses();
                Process eqProcess = null;
                foreach (Process p in ps)
                {
                    if (p.MainWindowTitle == "EQW beta 2.35a")
                    {
                        eqProcess = p;
                        break;
                    }
                }
    
                //listBox1.Items.Add(eqProcess.MainWindowHandle);
    
                IntPtr ptr = eqProcess.MainWindowHandle;
    
                eqGraphic = Graphics.FromHwnd(ptr);
    
                font = new Font("Arial", 16);
                brush = new SolidBrush(Color.Black);
    
                timer1.Start();
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                eqGraphic.DrawString("HELLO", font, brush, new PointF(100, 100));
            }
    Sincerely,

    Martin Svendsen

  2. #2
    Join Date
    Feb 2008
    Posts
    79

    Re: Drawing On Top Of Another Application

    Im not sure this is not working for you, but at very least, I would get the graphics reference from within the timer and release it when done...

    Code:
    private void timer1_Tick(object sender, EventArgs e)
      {
      using(Graphics eqGraphic = Graphics.FromHwnd(ptr))
      {
        eqGraphic.DrawString("HELLO", font, brush, new PointF(100, 100));
      }
    }
    I would guess this is not working for you because you dont have the right pointer to create the graphics object, can you make it work first with a known graphics object... like inside a picturebox?
    Cheers,
    Jon

  3. #3
    Join Date
    Dec 2006
    Posts
    203

    Re: Drawing On Top Of Another Application

    Quote Originally Posted by jon.borchardt
    Im not sure this is not working for you, but at very least, I would get the graphics reference from within the timer and release it when done...

    Code:
    private void timer1_Tick(object sender, EventArgs e)
      {
      using(Graphics eqGraphic = Graphics.FromHwnd(ptr))
      {
        eqGraphic.DrawString("HELLO", font, brush, new PointF(100, 100));
      }
    }
    I would guess this is not working for you because you dont have the right pointer to create the graphics object, can you make it work first with a known graphics object... like inside a picturebox?
    Well, I released the graphic object in the FormClosing event instead, I don't know what's more efficient.

    The problem isn't that it doesn't paint it in the window (it does), but that it instantly disappears, thus if I increase the interval number for the timer, the text instantly disappears and reappears at a decreased interval.

    I don't know if this is a question for a GDI forum instead, perhaps?
    Sincerely,

    Martin Svendsen

  4. #4
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Drawing On Top Of Another Application

    I would guess that if its a graphics application the graphics is redrawn by the program iitself, in which you are trying to draw. I dont know ifit is possible to hook into the message chain of this application and reading out paint events. But if possible then I would try to draw synchron just after eacg paint event is done. ( Never tried such things so maybe only an idea )
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  5. #5
    Join Date
    Dec 2006
    Posts
    203

    Re: Drawing On Top Of Another Application

    Quote Originally Posted by JonnyPoet
    I would guess that if its a graphics application the graphics is redrawn by the program iitself, in which you are trying to draw. I dont know ifit is possible to hook into the message chain of this application and reading out paint events. But if possible then I would try to draw synchron just after eacg paint event is done. ( Never tried such things so maybe only an idea )
    I couldn't find any way to do this, but I'd be interested if anyone knew.

    What I did find out was that the timer was too slow, and instead I created a thread, made it run a function, and just Thread.Sleep(5) and it wouldn't flicker at all (or rather it would write faster than EQ would update).
    So this is a very hack solution, which isn't a very good solution (a terrible one to say the least), so if anyone comes up with another way of doing it, I'd be very interested in it.
    Sincerely,

    Martin Svendsen

  6. #6
    Join Date
    Sep 2004
    Posts
    1,361

    Re: Drawing On Top Of Another Application

    If this is a game that uses DirectX then it most likely doesn't use the WM_PAINT method to drive it's rendering. One of the first things they tell you is to make your own timer or loop to call the render function instead of using WM_PAINT.

    So if you are trying to key off WM_PAINT then you are not in synch with the application's render function.

    The best way to do this is simply to create your own 'window' on the render device and make your own polygon in 2D space and place it on the highest (or lowest) Z level possible. Draw your information on that.

    There might be a hook or callback you can get when a device calls the method to Clear or BeginDraw methods (I forgot their exact names) so you know when to re-draw your polygon.

  7. #7
    Join Date
    Dec 2006
    Posts
    203

    Re: Drawing On Top Of Another Application

    Quote Originally Posted by DeepT
    If this is a game that uses DirectX then it most likely doesn't use the WM_PAINT method to drive it's rendering. One of the first things they tell you is to make your own timer or loop to call the render function instead of using WM_PAINT.

    So if you are trying to key off WM_PAINT then you are not in synch with the application's render function.

    The best way to do this is simply to create your own 'window' on the render device and make your own polygon in 2D space and place it on the highest (or lowest) Z level possible. Draw your information on that.

    There might be a hook or callback you can get when a device calls the method to Clear or BeginDraw methods (I forgot their exact names) so you know when to re-draw your polygon.
    I was looking for exactly something like this, but is that possible in GDI?
    Sincerely,

    Martin Svendsen

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured