Subclassing the form titlebar & other stuffs
The simplest way to do that is to subclass the title bar by a vfp control as container and embed in it what vfp controls we want.
this is the method described in the sample i ship below.
This makes a some skin to the native vfp form
see some screenshots in the section below.
The top level form used in the project have a subclassed titlebar made with a container.
the native titlebar is cut with the form property form.titlebar=0
can embed in this container any vfp objects (textbox,editbox,image, spinner,label,container... .)
must resize the container in the resize form method.
-the standard menu (left icon or image) is not standard colored (see with editing the ymenu.mnx)
-the second menu (top level form) is positionned at line3 to be under the titlebar with this code line (you can position it as you want) :
DEFINE MENU (m.cMenuName) IN (m.oFormRef.Name) BAR at line 3.
the menu mpr generated is saved as a prg sdiform.prg otherwise the menu is always above the titlebar.in the form init execute :[do sdiform.prg with this,.t.] instead an mpr.
this trick necessits only the mpr as prg file (no menu embed).
The form is limited when resizing with the minWidth & minHeight properties.
Can customize the background titlebar (random or set as an image in "image folder"), the caption(property form.ycaption.Forecolor) and the form picture.....
can add fontname,fontsize...but its not the goal here.I just focus on how to do that operation
Can set the transparency between opacity=100-255 (values <100 are very transparent).A
normal good opacity value is 210 (set initially on the form).
When setting transparency change the color with some units(+-) to see the change on form.
Can make a hole on form playing with the key (#Define LWA_COLORKEY 1) instead alpha channel(#Define LWA_ALPHA 2) or both the 2 constants.
Can clear this hole by setting new transparency to 255
Of course the form is movable by the titlebar
A hole with tranpsarency 0 can make the desktop icons clickable(hrere opacity>100 then no problem).
I added a menu on the top level form (showWindow=2 only) for demo.(coded in sdiform.prg)
Click on the left icon or on the image to fire thecontextuel menu(you can extend it in the visual menu on project)
Download the entire proj , test it and generate an exe with your vfp9 version.
i added a large quantity of small pictures in the "image" folder (can filter or change).
*remarks
-can add many items to menu as your taste
-can make small images in the container (minimize,max and close)
Some screenshots made on running application
the zip contains the entire project ytitlebar-feed back me if any problem.
Click on code to select [then copy] -click outside to deselect
![]()
*2*created on 11 of january 2017 (user question on UT) *--yposition_any_window.prg *-- starting with Listing child windows for the Windows desktop-Nesw2News *--adapted to search a specific window done with its title caption . *--browse the result with informations on hwnd,window dimensions,title window,visibility,class (as option) *--suppose 1 single instance of window with mycaption title.(it takes the first window) *--window caption is localized (microsoft windows)...must put the exact localized title to search.change *--titles below (for french locale) *--the setwindoxPos API can position any window given by its handlecan set left,top,width & height *begin code _Screen.WindowState=1 Local mycaption *mycaption="Sans titre - Paint" *run/n mspaint *myCaption="Sans titre - Bloc-notes" *run/n notepad mycaption="Explorateur de fichiers" &&warning loclized (here french---in english: files explorer... must be exact title. Run/N explorer.Exe Inke(3) &&wait to make window appear for positionning it #Define GW_HWNDLAST 1 #Define GW_HWNDNEXT 2 #Define GW_CHILD 5 Do Declare Create Cursor csResult (HWnd N(12), isvisible N(1),; leftpos I, toppos I, rightpos I, botpos I, wincap C(100), classname C(64)) Local hDesktop, hFirstChild, hLastChild, rc, cWinCap, cWinClass,; nVisible, nLeft, nTop, nRight, nBottom hDesktop = GetDesktopWindow() hFirstChild = GetWindow(hDesktop, GW_CHILD) hLastChild = GetWindow(hFirstChild, GW_HWNDLAST) hCurrent = hFirstChild Do While .T. cWinCap = GetWinText(hCurrent) cWinClass= GetClsName(hCurrent) nVisible = IsWindowVisible(hCurrent) rc = Repli(Chr(0),16) = GetWindowRect(hCurrent, @rc) nLeft = buf2dword(Substr(rc, 1,4)) nTop = buf2dword(Substr(rc, 5,4)) nRight = buf2dword(Substr(rc, 9,4)) nBottom = buf2dword(Substr(rc, 13,4)) ***********test searched window here If Allt(Lower(mycaption)) == Allt(Lower(cWinCap)) Insert Into csResult Values (hCurrent, nVisible,; nLeft, nTop, nRight, nBottom, cWinCap, cWinClass) Endi If hCurrent = hLastChild Exit Endif hCurrent = GetWindow(hCurrent, GW_HWNDNEXT) Enddo Locate *BROWSE NORMAL NOWAIT && for isvisible=1 If Reccount()=0 Messagebox("Window ["+mycaption+" ] not found...cancelling",16+4096,"error",1500) Return .F. Endi lnHandle=HWnd If HWnd=0 Messagebox("fails! no window on desktop....cancelling!",16+4096,"error",1500) Return .F. Endi *position window here-this is tests for 6 positions Local xleft,xtop,xwidth,xheight &&as you want m.xwidth=500 m.xheight=200 SetWindowPos(m.lnHandle,0, 0,0,m.xwidth+100,m.xheight-50,64) Inke(1) SetWindowPos(m.lnHandle,0, 100,0,m.xwidth,m.xheight+100,64) Inke(1) SetWindowPos(m.lnHandle,0, 100,300,m.xwidth-50,m.xheight,64) Inke(1) SetWindowPos(m.lnHandle,0,400,50,m.xwidth,m.xheight+40,64) Inke(1) SetWindowPos(m.lnHandle,0, 50,500,m.xwidth+100,m.xheight+100,64) Inke(1) *centered on screen m.xwidth=xwidth+200 m.xheight=m.xheight+200 SetWindowPos(m.lnHandle,0,(Sysmetric(1)-xwidth)/2,(Sysmetric(2)-xheight)/2,m.xwidth,m.xheight,64) Retu Function GetClsName(hWindow) Local nBufsize, cBuffer cBuffer = Repli(Chr(0), 250) nBufsize = GetClassName(hWindow, @cBuffer, Len(cBuffer)) Return Substr(cBuffer, 1, nBufsize) Function GetWinText(hWindow) * returns window title bar text -- Win9*/Me/XP/2000 Local cBuffer, nResult cBuffer = Space(250) nResult = GetWindowText(hWindow, @cBuffer, Len(cBuffer)) Return Substr(cBuffer, 1, nResult) endfunc Function buf2dword(lcBuffer) Return Asc(Substr(lcBuffer, 1,1)) + ; BitLShift(Asc(Substr(lcBuffer, 2,1)), 8) +; BitLShift(Asc(Substr(lcBuffer, 3,1)), 16) +; BitLShift(Asc(Substr(lcBuffer, 4,1)), 24) endfunc Procedure Declare Declare Integer GetDesktopWindow In user32 Declare Integer GetWindow In user32 Integer HWnd, Integer wFlag Declare Integer GetWindowRect In user32 Integer HWnd, String @lpRect Declare Integer IsWindowVisible In user32 Integer HWnd Declare Integer GetWindowText In user32; INTEGER HWnd, String @lpString, Integer cch Declare Integer GetClassName In user32; INTEGER HWnd, String lpClassName, Integer nMaxCount Declare Integer SetWindowPos In user32; INTEGER HWnd, Integer hWndInsertAfter,; INTEGER x, Integer Y, Integer cx, Integer cy,; INTEGER wFlags endproc *endcode *can use findwindow to get the window but i prefer this code(for another uses).