AHK Main Window(MW)

Share the finished AutoHotkey v2 Scripts and libraries you made here. Please put the current version of AutoHotkey v2 you used in Square Brackets at the start of the topic title.
xroot
Posts: 11
Joined: 21 Jun 2019, 08:45

AHK Main Window(MW)

Post by xroot » 15 Mar 2020, 10:22

AutoHotkey's MW is usually hidden, but can be shown via the tray icon.
#NoTrayIcon = no tray icon.

"A_ScriptHwnd" can be used to work with the MW.

Wanted to see if I could use the ready made Gui(MW) without crashing.

The MW has a menu control and edit control.
These controls can be used if you need them.

First, I created or changed the Message Loop for my own Gui(MW).
I then removed the two controls (menu,edit) to start with a clean Gui(MW).
Setup the background color.

In the message loop I created a button, static, statusbar control, alot like how C++ does it.
Even setup "No Focus Dots" on the button control.

It seems to run fine and stable for an unusual Gui(MW).
It might not be a good idea to use the MW, but it was fun playing with a ready made Gui(MW).

If you feel courageous try it and have some fun.

Code: Select all

#NoTrayIcon
#include winapi.ahk

Long_Date(){
    return &("`t" FormatTime(,"Time"))
}

No_FocusDots(hWnd,uMsg,wParam,lParam,uIdSubclass,dwRefData){
    if(uMsg = WM_SETFOCUS)
        return
    return DefSubclassProc(hWnd,uMsg,wParam,lParam)
}

; Main Window Message Loop Function
Msg_Loop(hWnd,uMsg,wParam,lParam){
    static hBnd  := 0,Sbar := 0,hStat := 0,StaticID := 45,ExitID := 69,SbarID := 1002,NoDots := 0
          ,pan1  := "`tAHK Hidden Gui",pan2 := "`t" StrReplace(FormatTime(,"LongDate")," 0"," ")
          ,hIcon := LoadPicture(A_ScriptDir "\nuke.ico",,IMAGE_ICON)
          ,nmm   := NMMOUSE.New(),SBparts := BufferAlloc(16,0),FontName := "Times New Roman",TimerID := 1979
    Switch(uMsg){
        Case WM_SYSCOMMAND,WM_COMMAND,WM_CHAR:
            If(wParam = SC_CLOSE || wParam = ExitID || wParam = IDCANCEL || wParam = Esc)
                DestroyWindow hWnd
        Case WM_TIMER:
            SendMessage SB_SETTEXTW,2,Long_Date(),Sbar
        Case WM_NOTIFY:
            If(wParam = SbarID){
                nmm.ptr := lParam
                iClick  := nmm.dwItemSpec + 1
                If(iClick >= 1 && iClick <= 3)
                    MsgBox StatusBarGetText(iClick,hWnd),"StatusBar Panel #" iClick,"Iconi t2"
                Else If(iClick = 4)
                    DestroyWindow hWnd
            }
        Case WM_SHOWWINDOW:
            SendMessage WM_SETICON,,LoadPicture(A_ScriptDir "\crapper.ico",,IMAGE_ICON),,hWnd
            NoDots := CallbackCreate("No_FocusDots")
            hBnd   := CreateWindowEx(WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,"Button","EXIT",WS_VISIBLE|WS_CHILD|WS_TABSTOP,630,235,120,45,hWnd,ExitID)
            hStat  := CreateWindowEx(0,"Static","Click Any StatusBar Item",WS_VISIBLE|WS_CHILD,120,60,627,65,hWnd,StaticID)
            Sbar   := CreateWindowEx(WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,"msctls_statusbar32","",WS_VISIBLE|WS_CHILD,,,,,hWnd,SbarID)
            SetWindowTheme Sbar    ;turn off visual effects
            SendMessage SB_SETBKCOLOR,,Cyan,Sbar
            SendMessage SB_SETMINHEIGHT,45,,Sbar
            hFont := CreateFont(35,,,,800,,,,,,,4,,FontName)
            SendMessage WM_SETFONT,hFont,true,hBnd
            hFont := CreateFont(55,,,,800,,true,,,,,4,,FontName)
            SendMessage WM_SETFONT,hFont,true,hStat
            hFont := CreateFont(28,,,,800,,,,,,,4,,FontName)
            SendMessage WM_SETFONT,hFont,true,Sbar
            SetWindowSubclass hBnd,NoDots,ExitID
            Set_Timer hWnd,TimerID,999
        Case WM_SIZE:
            sbSize := (lParam & 0xFFFF)/4
            NumPut "int",sbSize+StrLen(pan1),"int",sbSize*2.7,"int",sbSize*3.5,"int",-1,SBparts
            SendMessage SB_SETPARTS,4,SBparts,Sbar
            SendMessage SB_SETTEXTW,0,&pan1,Sbar
            SendMessage SB_SETTEXTW,1,&pan2,Sbar
            SendMessage SB_SETTEXTW,2,Long_Date(),Sbar
            SendMessage SB_SETICON,3,hIcon,Sbar
        Case WM_CTLCOLORSTATIC:
            SetBkColor wParam,Cyan
            return hCyan
        Case WM_DESTROY:
            KillTimer hWnd,TimerID
            RemoveWindowSubclass hBnd,NoDots,ExitID
            SetWindowLong hWnd,GWL_WNDPROC,ohWnd
            PostQuitMessage
    }
    return CallWindowProc(ohWnd,hWnd,uMsg,wParam,lParam)
}

; Start of Script
global Cyan  := 0xffff00
global hCyan := CreateSolidBrush(Cyan)

; SetUp Your Own Message Loop
global ohWnd := SetWindowLong(A_ScriptHwnd,GWL_WNDPROC,CallbackCreate("Msg_Loop"))

; Remove Edit Control From Main Window
WinClose ControlGetHwnd("Edit1",A_ScriptHwnd)

; Remove Menu Control From Main Window
SetMenu A_ScriptHwnd,0
; Set Background Color for Main Window
SetClassLong A_ScriptHwnd,GCL_HBRBACKGROUND,hCyan

msg := BufferAlloc(28,0)
w   := 800,h := 400

WinSetTitle "Use AHK Hidden Main Window",A_ScriptHwnd
WinSetStyle "-" WS_MAXIMIZEBOX,A_ScriptHwnd
WinSetStyle "-" WS_SIZEBOX,A_ScriptHwnd

WinMove (a_screenwidth-w)/2,(a_screenheight-h)/2,w,h,A_ScriptHwnd
WinShow A_ScriptHwnd

; Main Window Message Loop
While(GetMessage(msg.ptr)){
    TranslateMessage msg.Ptr
    DispatchMessage msg.Ptr
}
HiddenGui.zip
(4.22 KiB) Downloaded 56 times

Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: AHK Main Window(MW)

Post by Helgef » 15 Mar 2020, 12:54

I see different results on 32 bit build vs 64 bit build. Also,

Code: Select all

Long_Date(){
    return &("`t" FormatTime(,"Time"))
}
:arrow: a reminder.

Thanks for sharing, cheers.

lexikos
Posts: 7057
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: AHK Main Window(MW)

Post by lexikos » 23 May 2020, 03:31

SetUp Your Own Message Loop
That's a window procedure, not a message loop. Each program (usually) has only one message loop active at a time (per GUI thread), but it has one window procedure for each window class. The window procedure doesn't do any looping. It is called indirectly by DispatchMessage within the message loop, but may also be called by SendMessage without the message loop coming into play.

I would recommend avoiding the use of GetMessage in scripts. You can replace the message loop with #Persistent. AutoHotkey's message loop does a lot more than just call those three functions. It will still run automatically at intervals while your loop is running, but it will miss any messages that you've taken out with GetMessage. Any such messages will be dispatched directly without being handled by AutoHotkey's internal message loop. For some messages (that normally launch new script threads), that might just result in the message being placed straight back into the queue, and the process may repeat until the internal message loop catches the message.

I congratulate you for getting it to work. As you're probably aware, there are much easier ways to reuse the script's main window, but I'm not sure if there's a reason to do so. ;)

Post Reply

Return to “AutoHotkey v2 Scripts and Functions”