Sign in to follow this  
Followers 0
OldCoder

Title Bar Custom Button

6 posts in this topic

I've seen many queries about creating a custom button in the titlebar, and have also seen many interesting work-arounds for doing such a thing, (mostly ones involving the creation of an independent popup GUI that chase the applications caption bar around the screen). I have, of course, tried AnyGUI, but this isn't really what I am looking for. I've been trying to actually attach a button to an application as if it were in the applications design so that no work-around is needed. I found the following NET Framework script that seemed very fundamental, and, hopefully, easier to convert. I am not a NET Framework programmer, so quite clueless is my attempt here.

NET FRAMEWORK CUSTOM TITLEBAR BUTTON:

using System;

using System.Drawing;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace WindowsFormsApplication1

{

public partial class CustomBorderForm : Form

{

const int WM_NCPAINT = 0x85;

[DllImport("user32.dll", SetLastError = true)]

public static extern IntPtr GetWindowDC(IntPtr hwnd);

[DllImport("user32.dll", SetLastError = true)]

public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

[DllImport("user32.dll", SetLastError = true)]

public static extern void DisableProcessWindowsGhosting();

[DllImport("UxTheme.dll", SetLastError = true, CharSet = CharSet.Unicode)]

public static extern IntPtr SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList);

public CustomBorderForm()

{

// This could be called from main.

DisableProcessWindowsGhosting();

InitializeComponent();

}

protected override void OnHandleCreated(EventArgs e)

{

SetWindowTheme(this.Handle, "", "");

base.OnHandleCreated(e);

}

protected override void WndProc(ref Message m)

{

base.WndProc(ref m);

switch (m.Msg)

{

case WM_NCPAINT:

{

IntPtr hdc = GetWindowDC(m.HWnd);

using (Graphics g = Graphics.FromHdc(hdc))

{

g.FillEllipse(Brushes.Red, new Rectangle((Width-20)/2, 8, 20, 20));

}

int r = ReleaseDC(m.HWnd, hdc);

}

break;

}

}

}

}

This is my very unsuccessful attempt at translating this into AutoIt code:

#Include <GDIPlus.au3>
#Include <WinAPI.au3>

Global $WM_NCPAINT=0x85

Global $GUI_Form1=GUICreate("", 400, 100)
$GUI_label=GUICtrlCreateLabel("", 0, 20, 400, 100)
GUISetState()

_GDIPlus_Startup()
$hDC=_WinAPI_GetWindowDC($GUI_Form1)
_WinAPI_ReleaseDC($GUI_Form1, $hDC)

#cs
The author said this is used only if drawing problems occur, (or somthing like that).

DllCall("user32.dll", "int", "DisableProcessWindowsGhosting")
#ce
$ret=SetWindowTheme($GUI_Form1)
GUICtrlSetData($GUI_label, " ERROR CODE: " & $ret[0] & @CRLF & " HANDLE,(To ?): " & $ret[1])
GUIRegisterMsg($WM_NCPAINT, "WM_NCPAINT")

While GUIGetMsg()<>-3

WEnd
_GDIPlus_Shutdown()




Func WM_NCPAINT($hWnd, $msg, $wParam, $lParam)

Switch $msg

    Case $WM_NCPAINT
        If NOT IsHWnd($hWnd) Then $hWnd=$GUI_Form1
        Local $hDC=_WinAPI_GetWindowDC($hWnd), $hGO=_GDIPlus_GraphicsCreateFromHDC($hDC), $wGP=WinGetPos($hWnd)
        _GDIPlus_GraphicsDrawRect($hGO, ($wGP[2]-20)/2, 8, 20, 20, 0)
        _WinAPI_ReleaseDC($hWnd, $hDC)
EndSwitch

Return "GUI_RUNDEFMSG"

EndFunc

#cs
    SetWindowTheme

        Causes a window to use a different set of visual style information than its class normally uses. Returns S_OK if successful, HRESULT error code if not.


    $hWnd=      Handle to the window whose visual
            style information is to be changed.

    $pSAN=      Pointer to a string that contains the
            application name to use in place of the calling application's name. If this parameter is NULL, the calling application's name is used.

    $pSIL=      Pointer to a string that contains a
            semicolon-separated list of CLSID names to use in place of the actual list passed by the window's class. If this parameter is NULL, the ID list from the calling class is used.


    RETURNS:    If the method succeeds, it returns
            S_OK. Otherwise, it returns an HRESULT error code.

#ce

Func SetWindowTheme($hWnd, $pSAN="", $pSIL="")

Local $a=DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $hWnd, "ptr", $pSAN, "ptr", $pSIL)
Return $a

EndFunc

This uses UxTheme DLL to set up the customization, (I guess), and some kind of drawing to a rectangle, (the button, I assume). Other then all my widely speculative assumptions, the code seems fairly straight forward. Can anyone give me a hand with this, I am completely lost?


"Intelligence is the ability to adapt to change."                                      - Stephen Hawking                                        "...not the ability to exploit others."                                                  - OldCoder

Share this post


Link to post
Share on other sites



BTW, I am digging the new forum look and functionality. Nice work guys. :)


"Intelligence is the ability to adapt to change."                                      - Stephen Hawking                                        "...not the ability to exploit others."                                                  - OldCoder

Share this post


Link to post
Share on other sites

No one has any ideas? I was sure someone from this forum could figure this out. I know I can't. :)


"Intelligence is the ability to adapt to change."                                      - Stephen Hawking                                        "...not the ability to exploit others."                                                  - OldCoder

Share this post


Link to post
Share on other sites

Have a look at my FunSkin UDF.

Just search for it.


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

Have a look at my FunSkin UDF.

Just search for it.

Very interesting. I am not sure what I am looking at yet. Is it an actual way to create real GUIs with customizable controls, titlebars, etc., or is it a work-around, like removing the titlebar from the GUI and using an image for the titlebar, buttons, etc.? I must say, it's quite lovely. Kudos. :)

Either way, thanks for your reply. Cheers. ;)


"Intelligence is the ability to adapt to change."                                      - Stephen Hawking                                        "...not the ability to exploit others."                                                  - OldCoder

Share this post


Link to post
Share on other sites

FunSkin is resizing titlebar and border size with the message WM_NCCALCSIZE and overpainting the NC region

It changes the styles of the windows to have no standard titlebar buttons, so that you can create your own buttons without being overpainted.

That's all.


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0