Working with windows handles and APIs- Part I

Published on by Yousfi Benameur

8 codes in this first part of windows ,handles and APIs showing how to manipulate any window, having a handle.

In VFP , only forms are considered as Windows real object and have their handleThis integer,distributed by the system  is used to make all operations by the windows OS , begining with creating objects and manipulating them with PEM.

All these 8 codes are tested on win8.1/win10

*1--This code removes the titlebar of any window

Tested on Notepad,mspaint,calc,snippingtool....
recent IE and FF have modified this behavior and dont work with this code.Some new applications avoid this by internal code and dont accepts cutted titlebar.
ALT+F4 to close window (here without titlebar)
or with file menu if exists.

 


*Begin Code

Do ydeclare

If ! ShellExecute(0, "open", "notepad.exe","","",0)>32
Messagebox("An error was occured !",16+4096,"Error",1000)
Return .F.
Endi
sleep(3000)
Local m.xtitle
m.xtitle="Sans titre - Bloc-notes "
&&warning ! localized (depends on langage on use in system)
Do yprocess With m.xtitle

Procedure yprocess
Lparameters ytitle

*Important: must be the EXACT Caption of the window depending on language used on system-place it in the form
Local i,fail,yhwnd
i=0
fail=.F.
yhwnd=0
Do While yhwnd=0
yhwnd = FindWindow(Null, Allt(ytitle))
&&localized
sleep(1000)
i=i+1

If i>5
m.fail=.T.
Exit
Endi
Enddo
If m.fail=.T.
Messagebox("Fail top find "+ytitle,16+4096,"error",1000)
Return .F.
Endi
#Define SW_SHOW 5
ShowWindow(yhwnd,SW_SHOW)
Do ycut_titlebar With yhwnd
Endproc


*Cut the titlebar
Procedure ycut_titlebar
Lparameters HWnd
#Define GWL_STYLE -16
#Define WS_CAPTION 0x00C00000

Local lnStyle, lnNewStyle
* Get the current style of the window
lnStyle = GetWindowLong(HWnd, GWL_STYLE)
* Remove the border of the window
lnNewStyle = Bitxor(lnStyle, WS_CAPTION) -0xCF0000

* Set the new style for the window
=SetWindowLong(HWnd, GWL_STYLE, lnNewStyle)
Messagebox("ALT+F4 to close the window or by menu",0+32+4096,'',1200)
Endproc

Procedure ydeclare
Declare Integer FindWindow In user32;
STRING lpClassName, String lpWindowName
Declare Integer Sleep In kernel32 Integer

Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex
Declare Integer SetWindowLong In user32 Integer HWnd,;
INTEGER nIndex, Integer dwNewLong
Declare Integer ShowWindow In user32;
INTEGER HWnd,;
INTEGER nCmdShow
Declare Integer ShellExecute In SHELL32.Dll Integer nWinHandle,;
STRING cOperation,;
STRING cFileName,;
STRING cParameters,;
STRING cDirectory,;
INTEGER nShowWindow

DECLARE INTEGER ShowWindow IN user32 INTEGER hwnd, INTEGER nCmdShow

Endproc

*End code


*2-*This change the titlebar caption (text)  of any window

*Begin code

Do yDeclare
*Run/N explorer
If ! ShellExecute(0, "open", "Explorer.exe","","",0)>32 
&&hidden
    Messagebox("An error was occured !",16+4096,"Error",1000)
    Return .F.
Endi

sleep(1000)

#Define SW_SHOWNORMAL        1
#Define ccCustomTitle      "my Custom Explorer title"

Local hCalc
* retrieves explorer window hanlde
m.yHWND = GetWinHandle()
Messagebox(Trans(yHWND),0+32+4096,'',1000)
* change the text of the title bar
= SetWindowText (yHWND , ccCustomTitle)


Function  GetWinHandle
    Local HWnd,i
    i=0
    HWnd=0
    Do While HWnd=0
        HWnd = FindWindow (.Null., ccCustomTitle)
        sleep(100)
        If HWnd = 0
            i=i+1
            * Search for the window (handle)
            HWnd = FindWindow (.Null.,
"Explorateur de fichiers")   &&Warning explorer window title localized
            If i>10
                Exit
            Endi
        Endif
    Enddo

    #Define SW_SHOW 5
    ShowWindow(HWnd,SW_SHOW)
    Return HWnd

Procedure  yDeclare
    Declare Integer SetWindowLong In user32;
        INTEGER HWnd, Integer nIndex, Integer dwNewLong

    Declare Integer FindWindow In user32;
        STRING lpClassName, String lpWindowName

    Declare Integer GetWindowLong In user32;
        INTEGER HWnd, Integer nIndex

    Declare Integer ShellExecute In SHELL32.Dll Integer nWinHandle,;
        STRING cOperation,;
        STRING cFileName,;
        STRING cParameters,;
        STRING cDirectory,;
        INTEGER nShowWindow

    Declare Integer SetWindowText In user32;
        INTEGER HWnd, String lpString

    Declare Integer Sleep In kernel32 Integer

DECLARE INTEGER ShowWindow IN user32 INTEGER hwnd, INTEGER nCmdShow

*End code


*3-*This code  removes  all the system menu from a window (located on the titlebar)

*Begin Code

Do ydeclare

If ! ShellExecute(0, "open", "notepad.exe","","",1)>32
Messagebox("An error was occured !",16+4096,"Error",1000)
Return .F.
Endi
sleep(2000)
Local m.xtitle
m.xtitle="Sans titre - Bloc-notes " &&warning ! localized (depends on langage on use in system)
Do yprocess With m.xtitle

Procedure yprocess
Lparameters ytitle
*Important: must be the EXACT Caption of the window depending on language used on system-place it in the form
Local i,fail,yhwnd
i=0
fail=.F.
yhwnd=0
Do While .t.
yhwnd = FindWindow(Null, Allt(ytitle)) &&localized
sleep(100)
i=i+1
if ! m.yhwnd=0
exit
endi

If i>20
m.fail=.T.
Exit
Endi
Enddo

If m.fail=.T.
Messagebox("Fail top find "+ytitle,16+4096,"error",1000)
Return .F.
Endi

Do ytask With yhwnd
Endproc

*
Procedure yTask
Lparameters HWnd
#Define GWL_STYLE -16
#Define WS_CAPTION 0x00C00000
#Define WS_SYSMENU  524288

Local lnStyle, lnNewStyle
* Get the current style of the window
lnStyle = GetWindowLong(HWnd, GWL_STYLE)
* Remove the SYSTEM MENU of the window
lnNewStyle = Bitxor(lnStyle, WS_SYSMENU)

* Set the new style for the window
=SetWindowLong(HWnd, GWL_STYLE, lnNewStyle)
Messagebox("ALT+F4 to close the window or by menu",0+32+4096,'',1200)
Endproc

Procedure ydeclare
Declare Integer FindWindow In user32;
STRING lpClassName, String lpWindowName
Declare Integer Sleep In kernel32 Integer

Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex
Declare Integer SetWindowLong In user32 Integer HWnd,;
INTEGER nIndex, Integer dwNewLong
Declare Integer ShowWindow In user32;
INTEGER HWnd,;
INTEGER nCmdShow
Declare Integer ShellExecute In SHELL32.Dll Integer nWinHandle,;
STRING cOperation,;
STRING cFileName,;
STRING cParameters,;
STRING cDirectory,;
INTEGER nShowWindow
Endproc

*End code


*4-**This code can removes the titlebar system menu
*can removes the maximize button
*can removes the minimize button
*can removes the maximize+minimize buttons

*Begin Code

Do ydeclare

If ! ShellExecute(0, "open", "notepad.exe","","",1)>32
Messagebox("An error was occured !",16+4096,"Error",1000)
Return .F.
Endi
sleep(2000)
Local m.xtitle
m.xtitle="Sans titre - Bloc-notes " &&warning ! localized (depends on langage on use in system)
Do yprocess With m.xtitle

Procedure yprocess
Lparameters ytitle
*Important: must be the EXACT Caption of the window depending on language used on system-place it in the form
Local i,fail,yhwnd
i=0
fail=.F.
yhwnd=0
Do While .t.
yhwnd = FindWindow(Null, Allt(ytitle)) &&localized
sleep(100)
i=i+1
if ! m.yhwnd=0
exit
endi

If i>20
m.fail=.T.
Exit
Endi
Enddo

If m.fail=.T.
Messagebox("Fail top find "+ytitle,16+4096,"error",1000)
Return .F.
Endi

Do ytask With yhwnd
Endproc

Procedure yTask
Lparameters HWnd
#Define GWL_STYLE -16
#Define WS_CAPTION 0x00C00000

#Define WS_SYSMENU  524288

#DEFINE WS_MINIMIZEBOX  0x20000
#DEFINE WS_MAXIMIZEBOX  0x10000

Local lnStyle, lnNewStyle
* Get the current style of the window
lnStyle = GetWindowLong(HWnd, GWL_STYLE)

*can try a combination of these constants and see the result on window(uncomment one by one)
* Remove the SYSTEM MENU of the window
*lnNewStyle = Bitxor(lnStyle, WS_SYSMENU)
*lnNewStyle = Bitxor(lnStyle,WS_MAXIMIZEBOX)    
*lnNewStyle = Bitxor(lnStyle-,WS_MINIMIZEBOX)    

lnNewStyle = Bitxor(lnStyle, WS_MAXIMIZEBOX,WS_MINIMIZEBOX)   
* Set the new style for the window
=SetWindowLong(HWnd, GWL_STYLE, lnNewStyle)
Messagebox("ALT+F4 to close the window or by menu",0+32+4096,'',1200)
Endproc

Procedure ydeclare
Declare Integer FindWindow In user32;
STRING lpClassName, String lpWindowName
Declare Integer Sleep In kernel32 Integer

Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex
Declare Integer SetWindowLong In user32 Integer HWnd,;
INTEGER nIndex, Integer dwNewLong
Declare Integer ShowWindow In user32;
INTEGER HWnd,;
INTEGER nCmdShow
Declare Integer ShellExecute In SHELL32.Dll Integer nWinHandle,;
STRING cOperation,;
STRING cFileName,;
STRING cParameters,;
STRING cDirectory,;
INTEGER nShowWindow
Endproc

*End code

*5-This code can manipulate the windows system menu (left of titlebar) and
can add to this menu custom items (with custom actions to do by user).
the menu can be removed and can restore the initial menu.
the windows messages are trapped in method form.handlewinmsg().
can click or rightclick on form titlebar to fire the system menu (for top
level form only as here) or on left titlebar icon.

*Begin code
Publi oform
oform=Createobject("ywinform")
oform.Show
Read Events
Retu
*
Define Class ywinform As Form
    Top = 42
    Left = 202
    Height = 378
    Width = 583
    ShowWindow = 2
    Caption = "Manipulate system menu"
    ControlBox = .T.
    Icon = "shell32_194.ico"
    noldproc = 0
    added = .F.
    Name = "Form1"

    Add Object command1 As CommandButton With ;
        Top = 324, ;
        Left = 276, ;
        Height = 25, ;
        Width = 132, ;
        Anchor = 768, ;
        Caption = "Reset system  menu", ;
        MousePointer = 15, ;
        Name = "Command1"

    Add Object command2 As CommandButton With ;
        Top = 324, ;
        Left = 120, ;
        Height = 25, ;
        Width = 132, ;
        Anchor = 768, ;
        Caption = "Reset New menu", ;
        MousePointer = 15, ;
        Name = "Command2"

    Add Object edit1 As EditBox With ;
        FontSize = 11, ;
        Anchor = 15, ;
        BorderStyle = 0, ;
        Height = 160, ;
        Left = 60, ;
        ReadOnly = .T., ;
        ScrollBars = 0, ;
        Top = 72, ;
        Width = 445, ;
        BackColor = Rgb(255,255,149), ;
        DisabledBackColor = Rgb(253,252,189), ;
        Name = "Edit1"

    Procedure handlewinmsg
        Lparameters HWnd As Integer, Msg As Integer, wParam As Integer, Lparam As Integer
        #Define GWL_WNDPROC -4
        #Define WM_SYSCOMMAND 0x0112
        #Define MF_STRING 0
        #Define SC_CLOSE 0xF060
        #Define NEWMENUITEMID1 1001
        #Define NEWMENUITEMID2 1002
        #Define NEWMENUITEMID3 1003
        #Define NEWMENUITEMID4 1004
        #Define NEWMENUITEMID5 1005

        Do Case
            Case Msg = WM_SYSCOMMAND And wParam = NEWMENUITEMID1
                Messagebox("You've clicked the new menu item1",0+32+4096,'',1000)
            Case Msg = WM_SYSCOMMAND And wParam = NEWMENUITEMID2
                Messagebox("You've clicked the new menu item2",
0+32+4096,'',1000)
            Case Msg = WM_SYSCOMMAND And wParam = NEWMENUITEMID3
                Messagebox("You've clicked the new menu item3",
0+32+4096,'',1000)
            Case Msg = WM_SYSCOMMAND And wParam = NEWMENUITEMID4
                Messagebox("You've clicked the new menu item4",
0+32+4096,'',1000)
            Case Msg = WM_SYSCOMMAND And wParam = NEWMENUITEMID5
                Messagebox("You've clicked the new menu About",
0+32+4096,'',1000)

            Case Msg = WM_SYSCOMMAND And wParam = SC_CLOSE
                Messagebox("You've clicked the Close button",
0+32+4096,'',1000)
                Thisform.Release()
            Otherwise
                Return CallWindowProc(This.noldproc, HWnd, Msg, wParam, Lparam)
        Endcase
    Endproc

    Procedure buildmenu
        #Define GWL_WNDPROC -4
        #Define WM_SYSCOMMAND 0x0112
        #Define MF_STRING 0
        #Define SC_CLOSE 0xF060
        #Define NEWMENUITEMID1 1001
        #Define NEWMENUITEMID2 1002
        #Define NEWMENUITEMID3 1003
        #Define NEWMENUITEMID4 1004
        #Define NEWMENUITEMID5 1005

        If Thisform.added=.F.
            Thisform.added=.T.
            * Get hold of the system menu (of this form)
            lnhSysPopup = GetSystemMenu(This.HWnd, 0)

            * Add our custom menu item at the botton of the list
            AppendMenu(lnhSysPopup, MF_STRING, NEWMENUITEMID1, "My New Menu Item1")
            AppendMenu(lnhSysPopup, MF_STRING, NEWMENUITEMID2, "My New Menu Item2")
            AppendMenu(lnhSysPopup, MF_STRING, NEWMENUITEMID3, "My New Menu Item3")
            AppendMenu(lnhSysPopup, MF_STRING, NEWMENUITEMID4, "My New Menu Item4")
            AppendMenu(lnhSysPopup, MF_STRING, NEWMENUITEMID5, "About")
        Endi
    Endproc

    Procedure Destroy
        Clea Events
    Endproc

    Procedure KeyPress
        Lparameters nKeyCode, nShiftAltCtrl
        If nKeyCode=27
            Thisform.Release
        Endi
    Endproc

    Procedure Activate
        Thisform.buildmenu()
    Endproc

    Procedure Init
        Thisform.noldproc = GetWindowLong(Thisform.HWnd, GWL_WNDPROC)
        Bindevent(Thisform.HWnd, WM_SYSCOMMAND,Thisform,"handlewinmsg",4)
    Endproc

    Procedure Load
        Declare Integer GetSystemMenu In User32 Integer HWnd, Integer bRevert
        Declare Integer AppendMenu In user32 ;
            INTEGER hMenu, Integer uFlags, Integer uIDNewItem, String @lpNewItem
        Declare Integer CallWindowProc In WIN32API ;
            INTEGER lpPrevWndFunc, Integer HWnd,Integer Msg,;
            INTEGER wParam, Integer Lparam
        Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex


        Declare Integer GetMenu In user32 Integer hWindow
        Declare Integer IsMenu In user32 Integer hMenu
        Declare Integer GetMenuItemCount In user32 Integer hMenu
        Declare Integer DrawMenuBar In user32 Integer hWindow

        Declare Integer DeleteMenu In user32;
            INTEGER hMenu, Integer uPosition,;
            INTEGER uFlags
    Endproc

    Procedure command1.Click
        With Thisform
            .ControlBox=.F.
            .ControlBox=.T.
            .added=.F.
        Endwith
    Endproc

    Procedure command2.Click
        Thisform.buildmenu()
    Endproc

    Procedure edit1.Init
        TEXT to this.value noshow
This code can manipulate the windows system menu (left of titlebar) and
can add to this menu custom items (with custom actions to do by user).
the menu can be removed and can restore the initial menu.
the windows messages are trapped in method form.handlewinmsg().
can click or rightclick on form titlebar to fire the menu (for top
level form only as here) or on left titlebar icon.
        ENDTEXT
    Endproc


Enddefine
*

*End code


*6-*This code moves any form with titlebar or no by mousedown
*Moving form  can be applied throw any object having this event(mousedown)

  1. *the form is moved even if there is some olecontrols on form.

*Begin code

Publi oform
oform=Newobject("ymove")
oform.Show
Read Events
Return
*
Define Class ymove As Form
    Top = 37
    Left = 36
    Height = 312
    Width = 611
    ShowWindow = 2
    ShowTips = .T.
    Caption = "Move a form with mousedown"
    KeyPreview = .T.
    Name = "Form1"

    Add Object shape1 As Shape With ;
        Top = 60, ;
        Left = 468, ;
        Height = 85, ;
        Width = 97, ;
        Curvature = 30, ;
        MousePointer = 15, ;
        ToolTipText = "MouseDow, me !", ;
        BackColor = Rgb(0,255,0), ;
        Name = "Shape1"

    Add Object label1 As Label With ;
        AutoSize = .T., ;
        FontSize = 12, ;
        Caption = "Move the form  by mousedown on form ,on image  or on shape with titlebar or no", ;
        Height = 21, ;
        Left = 24, ;
        Top = 24, ;
        Width = 431, ;
        Name = "Label1"

    Add Object check1 As Checkbox With ;
        Top = 72, ;
        Left = 108, ;
        Height = 17, ;
        Width = 59, ;
        AutoSize = .T., ;
        Alignment = 0, ;
        BackStyle = 0, ;
        Caption = "Titlebar", ;
        Value = 1, ;
        Name = "Check1"

    Add Object image1 As Image With ;
        Picture = Home(1)+"graphics\bitmaps\tlbr_w95\copy.bmp", ;
        Stretch = 2, ;
        Height = 108, ;
        Left = 180, ;
        MousePointer = 15, ;
        Top = 120, ;
        Width = 109, ;
        ToolTipText = "MouseDow, me !", ;
        Name = "Image1"

    Procedure MouseDown
        Lparameters nButton, nShift, nXCoord, nYCoord
        lnHandle = Thisform.HWnd    &&getFocus()
        param1 = 274
        param2 = 0xF012
        Declare Integer ReleaseCapture In WIN32API
        Declare Integer SendMessage In WIN32API Integer, Integer, Integer, Integer
        bb=ReleaseCapture()
        bb=SendMessage(lnHandle, param1, param2,0)
    Endproc

    Procedure KeyPress
        Lparameters nKeyCode, nShiftAltCtrl
        If nKeyCode=27
            Thisform.Release
        Endi
    Endproc

    Procedure shape1.MouseDown
        Lparameters nButton, nShift, nXCoord, nYCoord
        Thisform.MouseDown()
    Endproc

    Procedure check1.InteractiveChange
        Thisform.TitleBar=Iif(This.Value=0,0,1)
    Endproc

    Procedure image1.MouseDown
        Lparameters nButton, nShift, nXCoord, nYCoord
        Thisform.MouseDown()
    Endproc

    Procedure Destroy
        Clea Events
    Endproc

Enddefine
*

*EndCode


Working with windows handles and APIs- Part I
Working with windows handles and APIs- Part I
Working with windows handles and APIs- Part I

*7-*This code can hide and show the system taskbar

*Begin code
TEXT to myvar noshow
*This code hides the taskbar and the windows Start button until 10 sec and shows them again *
ENDTEXT
Messagebox(myvar,0+32+4096)

=hidetaskBar()
t0=Seconds()
Do While Seconds()-t0<=10
Enddo
=showtaskbar()
Messagebox("The taskbar & the win start button are shown again",0+32+4096)

Function hidetaskBar
    Declare Long FindWindow In "user32" String lpClassName, String lpWindowName
    Declare Long SetWindowPos In "user32" Long HWnd, Long hWndInsertAfter, Long x, Long Y, Long cx, Long cy, Long wFlags
    #Define WINDOWHIDE 0x80
    #Define WINDOWSHOW 0x40
    Local lnHandle
    lnHandle = FindWindow("Shell_TrayWnd", "")
    SetWindowPos(lnHandle, 0, 0, 0, 0, 0, WINDOWHIDE)
Endfunc

Function showtaskbar
    Declare Long FindWindow In "user32" String lpClassName, String lpWindowName
    Declare Long SetWindowPos In "user32" Long HWnd, Long hWndInsertAfter, Long x, Long Y, Long cx, Long cy, Long wFlags
    #Define WINDOWHIDE 0x80
    #Define WINDOWSHOW 0x40
    Local lnHandle
    lnHandle = FindWindow("Shell_TrayWnd", "")
    SetWindowPos(lnHandle, 0, 0, 0, 0, 0, WINDOWSHOW)
Endfunc

*End code


Click on code to select [then copy] -click outside to deselect


*8*
*added on  wednesday 14 octobre 2015; 19:55:43
*vfp opens prg file in a child window in normal state.How to open prg mawimized ?
*open any prg (or simular file as mpr,txt,htm,html,h open from visual foxpro xith modi comm)
* as maximized in vfp screen area.
*manually can use "ALT-" and then press "n" to maximize (in french localization).but i dont can make
*code working with this (tried keyboar') function ',shell.sendkeys,keybd_event apî unsuccessfully)! it seems that "ALT-" is a reserved windows key.

Declare Integer GetFocus In user32
*The return value is the handle to the window with the keyboard focus
Declare Integer ShowWindow In user32;
    INTEGER HWnd,;
	INTEGER nCmdShow

Local m.lcfilename
m.lcfilename=Getfile("prg;txt;mpr;h;html;htm" )
If Empty(m.lcfilename)
	Return .F.
Endi

#Define SW_MAXIMIZE     3  &&Specifies how the window is to be shown.here maximized
Modi File  (m.lcfilename ) Nowait  &&in window yb nowait
HWnd=GetFocus ()

=ShowWindow(HWnd, SW_MAXIMIZE)



To be informed of the latest articles, subscribe:
Comment on this post