Forcefully Embedded Applications

Miscellaneous Forums/Blitz Showcase/Forcefully Embedded Applications

I felt like going back into my embedded applications stuff, and I made this rather useful code to demonstrate its usefulness. It enables you to embed any program into yours.
I have coded it to only do Mozilla Firefox or Internet Explorer running www.blitzbasic.com (or any other page with the title "The Official Blitz Website"), but if you wanted to it wouldn't be too hard to make it work as you wanted using ExecFile and some command line stuff.
This post, in fact, is written inside of the very Blitz app that I am showcasing. Because of the window Hierarchy here, Blitz3d is not stealing window events, which is what usually happens with such things. What does all this mean? With a second of time getting the class name for a web browser, you can embed it inside of Blitz in about 5 seconds, allowing for some rather attractive help windows, and other such nice features. You could even, for example, have the windows calculator right inside of your blitz program, or solitaire, or Pain (t).

Now, also so you know, api_FindWindow does not search child windows. To search for the child windows of a window, you will need to change that function to api_FindWindowEx. This means that actually getting it inside of the actual web page content may need a little session with WinDowse.

;Force-Embedded Web Browser Demonstration
;By Dylan McCall
;June 23, 2005

;Win32 Consts:
Const GWL_STYLE = (-16)
Const WS_OVERLAPPED       = $00000000
Const WS_POPUP            = $80000000
Const WS_CHILD            = $40000000
Const WS_MINIMIZE         = $20000000
Const WS_VISIBLE          = $10000000
Const WS_DISABLED         = $08000000
Const WS_CLIPSIBLINGS     = $04000000
Const WS_CLIPCHILDREN     = $02000000
Const WS_MAXIMIZE         = $01000000
Const WS_CAPTION          = $00C00000
Const WS_BORDER           = $00800000
Const WS_DLGFRAME         = $00400000
Const WS_VSCROLL          = $00200000
Const WS_HSCROLL          = $00100000
Const WS_SYSMENU          = $00080000
Const WS_THICKFRAME       = $00040000
Const WS_GROUP            = $00020000
Const WS_TABSTOP          = $00010000
Const WS_MINIMIZEBOX      = $00020000
Const WS_MAXIMIZEBOX      = $00010000
Const WS_TILED            = $00000000
Const WS_ICONIC           = $20000000
Const WS_SIZEBOX          = $00040000
Const WS_POPUPWINDOW      = $80880000
Const WS_OVERLAPPEDWINDOW = $00CF0000
Const WS_TILEDWINDOW      = $00CF0000
Const WS_CHILDWINDOW      = $40000000

Const GWL_EXSTYLE = (-20)
Const WS_EX_DLGMODALFRAME     = $00000001
Const WS_EX_NOPARENTNOTIFY    = $00000004
Const WS_EX_TOPMOST           = $00000008
Const WS_EX_ACCEPTFILES       = $00000010
Const WS_EX_TRANSPARENT       = $00000020
Const WS_EX_MDICHILD          = $00000040
Const WS_EX_TOOLWINDOW        = $00000080
Const WS_EX_WINDOWEDGE        = $00000100
Const WS_EX_CLIENTEDGE        = $00000200
Const WS_EX_CONTEXTHELP       = $00000400
Const WS_EX_RIGHT             = $00001000
Const WS_EX_LEFT              = $00000000
Const WS_EX_RTLREADING        = $00002000
Const WS_EX_LTRREADING        = $00000000
Const WS_EX_LEFTSCROLLBAR     = $00004000
Const WS_EX_RIGHTSCROLLBAR    = $00000000
Const WS_EX_CONTROLPARENT     = $00010000
Const WS_EX_STATICEDGE        = $00020000
Const WS_EX_APPWINDOW         = $00040000
Const WS_EX_OVERLAPPEDWINDOW  = $00000300
Const WS_EX_PALETTEWINDOW     = $00000188
Const WS_EX_LAYERED           = $00080000

Const SWP_NOSIZE = $0001 
Const SWP_NOMOVE = $0002 
Const SWP_NOZORDER = $0004 
Const SWP_NOREDRAW = $0008 
Const SWP_NOACTIVATE = $0010 
Const SWP_FRAMECHANGED = $0020 
Const SWP_SHOWWINDOW = $0040 
Const SWP_HIDEWINDOW = $0080 
Const SWP_NOCOPYBITS = $0100 
Const SWP_NOOWNERZORDER = $0200 
Const SWP_NOSENDCHANGING = $0400 
Const SWP_DRAWFRAME = $0020 
Const SWP_NOREPOSITION = $0200 
Const SWP_DEFERERASE = $2000 
Const SWP_ASYNCWINDOWPOS = $4000 

Const SW_HIDE = 0 
Const SW_SHOWNORMAL = 1 
Const SW_NORMAL = 1 
Const SW_SHOWMINIMIZED = 2 
Const SW_SHOWMAXIMIZED = 3 
Const SW_MAXIMIZE = 3 
Const SW_SHOWNOACTIVATE = 4 
Const SW_SHOW = 5 
Const SW_MINIMIZE = 6 
Const SW_SHOWMINNOACTIVE = 7 
Const SW_SHOWNA = 8 
Const SW_RESTORE = 9 
Const SW_SHOWDEFAULT = 10 
Const SW_FORCEMINIMIZE = 11 
Const SW_MAX = 11 


;Known window Classes
Const FireFoxClass$="MozillaWindowClass"
Const FireFoxTitle$="The Official Blitz Website - Mozilla Firefox"

Const IEClass$="IEFrame"
Const IETitle$="The Official Blitz Website - Microsoft Internet Explorer"

Graphics 800,600,0,2

hWnd=SystemProperty("apphWnd")
style=api_GetWindowLong(hWnd,GWL_STYLE)
style=style Or WS_CLIPCHILDREN
api_SetWindowLong hWnd,GWL_STYLE,style

.findParent
parent=api_FindWindow(FireFoxClass,FireFoxTitle)		;You may add any other web browsers to this list by 
If parent=0 Then parent=api_FindWindow(IEClass,IETitle) ;copying that same line and changing the variables

Print "Will embed window with handle: "+Hex$(parent)
Print "Press any key to continue"
WaitKey
If parent=0 Then Goto findParent

api_SetParent parent,hWnd
SetGadgetShape parent,5,50,790,540 ;Making the embedded window fit nicely

styleEx=api_GetWindowLong(parent,GWL_EXSTYLE)
styleEx=styleEx Or WS_EX_TOOLWINDOW ;Looks cooler this way...
api_SetWindowLong parent,GWL_EXSTYLE,styleEx

style=api_GetWindowLong(parent,GWL_STYLE)
style=style Xor WS_THICKFRAME ;I have to do this, because it goes crazy when it's resized...
api_SetWindowLong parent,GWL_STYLE,style

api_UpdateWindow parent

Cls
Text 2,2, "Below is a Force-Embedded Window!"

Repeat
Until KeyDown(1)
api_DestroyWindow(parent)
End

;WinBlitz3d extract. To resize embedded window.
Function SetGadgetShape(gadget,x,y,width,height)

        r = api_BeginDeferWindowPos(1);
        t = api_DeferWindowPos(r,gadget,0,x,y,width,height,SWP_FRAMECHANGED Or SWP_SHOWWINDOW Or SWP_NOZORDER);
        api_EndDeferWindowPos(r);

        api_ShowWindow(gadget,SW_SHOW);
        ;api_SetActiveWindow(gadget);

End Function


What I find exceptionally cool here is that, thanks to the win32 api, I now have full control over the appearance of the web browser window.

You'll need User32.decls to run this. If you don't have it: http://www.blitzbasic.com/codearcs/codearcs.php?code=1179

Lastly, how to run this code: Have either Internet Explorer or Mozilla Firefox running, viewing BlitzBasic.com (or any other web site with the title "The Official Blitz Website"). Now, run the program, hit any key a few times (I recommend the space bar), and it's there!

There's a bit of artifacting to clear up, but this is just a very basic demonstration.

This also (sort of... not very well though yet) works in the opposite direction! I'll post Blitz in a web browser shortly, eventually followed by Blitz in a Java applet, which will be in this same thread (but I have no idea when that will be)

Works great.

Btw, how can you find the window class of certain program?

There's a program called WinDowse that does that and more:
http://www.greatis.com/delphicb/windowse/


I just modified it a bit, so that internet explorer is opened automatiically. now all you have to do is run the program. Which means: It works much better now :)

Still a bit clumsy because it first requires that the browser be openned in a seperate window, but, on my computer at least, it's loaded into the Blitz window so quickly that most people would hardly realize it was ever out.

For this example with ExecFile, I have removed the check for Firefox. The execFile thing actually does work with Firefox, but I have decided that IE is more compatible with the demo (and everybody has it).

I have also made some obvious changes to the window style for IE, which is now resizeable. (It was only Firefox that messed up the resizing... I think it also stole my window close button event).
;Force-Embedded Web Browser Demonstration
;By Dylan McCall
;June 23, 2005

;Win32 Consts:
Const GWL_STYLE = (-16)
Const WS_CLIPSIBLINGS     = $04000000
Const WS_CLIPCHILDREN     = $02000000
Const WS_CAPTION          = $00C00000

Const GWL_EXSTYLE = (-20)
Const WS_EX_TOOLWINDOW        = $00000080

Const SWP_NOZORDER = $0004 
Const SWP_FRAMECHANGED = $0020 
Const SWP_SHOWWINDOW = $0040 

Const SW_SHOW = 5 


;Known window Classes
Const FireFoxClass$="MozillaWindowClass"
Const FireFoxTitle$="The Official Blitz Website - Mozilla Firefox"

Const IEClass$="IEFrame"
Const IETitle$="http://www.blitzbasic.com/ - Microsoft Internet Explorer"
Const IETitle2$="The Official Blitz Website - Microsoft Internet Explorer"

Graphics 800,600,0,2

hWnd=SystemProperty("apphWnd")
style=api_GetWindowLong(hWnd,GWL_STYLE)
style=style Or WS_CLIPCHILDREN
api_SetWindowLong hWnd,GWL_STYLE,style

.findParent
;parent=api_FindWindow(FireFoxClass,FireFoxTitle)		;You may add any other web browsers to this list by 
;If parent=0 Then parent=api_FindWindow(IEClass,IETitle) ;copying that same line and changing the variables
ExecFile "iexplore.exe "+"http://www.blitzbasic.com/"
Local parent;,loops
Repeat
;	Print "Looping"
	parent=api_FindWindow(IEClass,IETitle) ;IE displays this title when loading the web site
	If parent = 0 Then parent= api_FindWindow(IEClass,IETitle2) ;If the web site has already been loaded, this title is displayed
	;loops = loops+1
Until parent <> 0 ;Or loops>10000

;Print "Will embed window with handle: "+Hex$(parent)
;Print "Press any key to continue"
;WaitKey
;If parent=0 Then Goto findParent

api_SetParent parent,hWnd
SetGadgetShape parent,5,50,790,540 ;Making the embedded window fit nicely

;styleEx=api_GetWindowLong(parent,GWL_EXSTYLE)
;styleEx=styleEx Or WS_EX_TOOLWINDOW ;Looks cooler this way...
;api_SetWindowLong parent,GWL_EXSTYLE,styleEx

style=api_GetWindowLong(parent,GWL_STYLE)
style=style Xor WS_CAPTION ;Looks more a part of the window now
api_SetWindowLong parent,GWL_STYLE,style

api_UpdateWindow parent

Cls
Text 2,2, "Below is a Force-Embedded Window!"

Repeat
Until KeyDown(1)
api_DestroyWindow(parent)
End

;WinBlitz3d extract. To resize embedded window.
Function SetGadgetShape(gadget,x,y,width,height)

        r = api_BeginDeferWindowPos(1);
        t = api_DeferWindowPos(r,gadget,0,x,y,width,height,SWP_FRAMECHANGED Or SWP_SHOWWINDOW Or SWP_NOZORDER);
        api_EndDeferWindowPos(r);

        api_ShowWindow(gadget,SW_SHOW);
        ;api_SetActiveWindow(gadget);

End Function


Does not work for me like it should (or i think it should)

When i start this ap a black window pops up (like every other blitzapp before graphics mode), and then internetexplorer pops up in another window, just like execfile. Not more not less.

That's strange then...
What web page is it showing?
What version of Internet Explorer do you have?

Put
Print "Blah"
Into the Repeat... Until loop (Line 111) and tell me if you get anything. (If it writes anything to the screen)


This is what it should look like:


see, THIS... i have a use for!

>Write synth Front End in VB again
>Write Engine in blitz.
>Imbed VB IDE into Blitz using the above code :D

coolies :D

Careful with it though, you may end up wasting a lot of time unless you can find out how to get that windows' handle using Win32. In the API-Guide tool ( http://www.mentalis.org/agnet/apiguide.shtml ) there's a list of most of (maybe all of) the ways that you can find a windows' handle. Just pop api_ onto the start of those commands, and, assuming you have user32.decls, they'll probably be highlighted.
You can also have the window to be embedded get its own handle and pass it to the Blitz3d window (for my case, this would be done by executing the b3d program with a window handle in the command line).

So, obviously, there are restrictions. api_ActiveWindow() is a command which I don't recommend, because it has a terrible success rate... For many others, the window needs a unique class name/window name that would not be used by other windows.

This could be used for the failing BlitzNCS project I started but now is dead.

Here a screen:



Strange...
Is that the theme your using which is removing the title bar on the IE window, or my program?
If it's the theme, then perhaps it's the getWindow() function being stupid...