How can I draw outside the form?

Hi everyone

I do face a new problem, I have a normal form, and a graphics object from the form's Paint(), and I am trying to draw something that will come on the top pf the form and little bit outside it

I need the draw something outside the form and to keep the form active (the focus over the form)

Is that possible



Answer this question

How can I draw outside the form?

  • keajatthew

    It seams I found the answer my self

    To draw directly on the desktop you need to use the windows API to get a hdc to the desktop, this is a simple code:

    Add this class to your code

    internal class WindowsAPI

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    public static extern IntPtr GetWindowDC(IntPtr hwnd); 
    [DllImport("user32.dll")] 
    public extern static IntPtr GetDesktopWindow();
    }

    Open a new form, drag a button to the form, and add this code to be executed when you press the button

    private void button1_Click(object sender, System.EventArgs e)
    {
    Graphics g;
    IntPtr hdc = WindowsAPI.GetWindowDC(WindowsAPI.GetDesktopWindow()); 
    g = Graphics.FromHdc(hdc);
    Pen p = new Pen(Color.Red);
    g.DrawLine(p,0,0,100,100);
    }


    Nice isn't :-)

    After two weeks of search I finally found the way, two weeks for a small piece of code, but it was worth it

  • Debra Dove

    Ok if this is complicated I can change the question little bit

    First of all, this is a sample of my new control library

    The custom dialog box
    http://members.rogers.com/tarazi/public_files/image0001.png

    The custom menu and some other controls that are under development
    http://members.rogers.com/tarazi/public_files/image0002.png


    Of course I am still learning the best way to design controls and to integrate them inside Microsoft Visual Studio.NET (Design Time), and my only problem today is with the menus

    I easily inherited the MenuItem class and the ContextMenu class and designed my own menu, that was easy, but the problem is that the inheritance of the above classes is not giving me the possibility to create the menus exactly as I imagine them.

    This is why I decided to create the menus from scratch, and I have two ideas:

    The first idea is to use GDI+ directly from a control or a component, and to draw the menus inside the form, and when the menu popup to be painted outside the form if necessary, but the question is "is that possible  (Can I draw directly on the desktop, without going to the Windows API)"

    The second idea is to use multiple forms, this will make my life much easier, but my only problem will be here the focus to the main form, so my second question is "is there is a way to show a form on a top on another form, and to keep the focus on both forms  Including the main form"

    I did some tests and I had a main form and another form that will stay on the top of the main form, that was easily done, but my only problem was the focus of the main form, once I touched the sub form the main form title bar changed (you know when the form is not active, in the background, it looks slightly different)


    I don't need the exact code to solve this, I know it takes time, but at least some hints :)

    Thanks

  • lololon

    There are a few alternatives for this issue that I think may be a little cleaner:

    1: This will create a non-TopLevel form that will be TopMost to all application windows:

    Me.AddOwnedForm(MySecondForm)
    MySecondForm.Show

    2: This will use the WS_CHILD constant as you define above, but not require a DLLImport:

    Public Class MySecondForm
    Inherits Form

    Private CONST WS_CHILD As Integer = &H40000000

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
           Get
                Dim cp As CreateParams = MyBase.CreateParams
                cp.Style = cp.Style OR WS_CHILD
                Return cp
           End Get
    End Property

    End Class

    That's all I can think of off the top of my head... Let me know if any of these help or if you have any questions.

  • Rich Hanbidge

    I created a sample that is inheriting the menu item and it is working fine by drawing the menus my self in the menu item, the problem is that is not working when drawing the main menu bar.

    The menu item can only draw itself on the menu bar, and there is no way to clear the menu bar and paint your own background, so if you use a nice color for the menu item, you will end up with a menu bar that is half painted and half not.

    You can’t change the size of that menu bar, you can’t do many things.


    If you have a reliable piece of code that can repaint the menu bar, you will solve part of my problem.


    In this image I am using the menu item inheritance to draw the context menu, and a control to draw the menu bar, but this is an old sample, and I have a lot of problems linking the menu list with the menu bar.

    http://members.rogers.com/tarazi/public_files/image0002.png

    <color="black;background-image: url(http://members.rogers.com/tarazi/public_files/image0002.png);width:770px;height:582px"></color>


  • Sergey Barskiy

    Yeah, the menu bar is not a control, its just a part of the window's non-client area. So the only way to custom paint it (that I know of) is to trap the WM_NCPAINT message. Getting that right though will put you in a world of pain(t). ;-) Creating your own menu bar control makes more sense. Especially if it means not having to build your own popup menu technology from scratch, which would be another world of pain.
  • Annie24372

    you should really call "releasedc" on the hdc you get from getwindowdc...

    otherwise you will get a big fat gdi leak there..

    //Roger

  • gpspilot

    Could you elaborate on why inheriting from the MenuItem and ContextMenu classes wasn't sufficient for your needs  What were your trying to do that couldn't be achieved by extending the base classes and customizing them with owner-draw and such  Sounds like the 'ground up' route you are taking will require 'reinventing the wheel' for a lot of fundamental menuing behavior.

    Iain Heath,
    Windows Forms.

  • Donna M-T

    I found the answer of another question my self again; it was how to have a form over another form (main form) without loosing the focus of the main form :)

    This is the basic idea; more lines of code are needed in order to show the second form properly.

    Form b = new Form();
    NativeAPI.SetWindowLong(b.Handle, NativeAPI.GWL_STYLE, NativeAPI.WS_CHILD);
    b.Show();

    public class NativeAPI
    {
    public const int GWL_STYLE = -16;
    public const long WS_CHILD = 0x40000000L;
    [DllImport("User32.dll", CharSet=CharSet.Auto)]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);
    }


    SetWindowLong is fantastic; I should’ve used it since long time

  • zmy

    sorry I had to post here, I have no answer for you.  I just wanted to contact you and your email seemed to be unavailable on this forum.

    I just wanted to asked you some questions about the screenshots you just posted, pretty impressive stuff!

    anyways, you can contact me via email at xinull@yahoo.com

    XiNull

  • How can I draw outside the form?