Using+an+ATL+container+control

//by Richard Russell, November 2006//

If, in your BBC BASIC program, you want to display a 'document' file (or other //registered// file type, such as an image file) you can very easily do that using **SYS "ShellExecute"**, as described in the [|main help documentation]. However that method causes a separate window to open in which the document is displayed.

You may instead prefer to display the document, image etc. in your own window, as if it is genuinely part of your program. This is relatively easily achieved using an **ATL container control**. Unlike the **ShellExecute** method you can only //view// a document, image etc.; you cannot edit it or save it to file.

The code below shows how to create a file viewer application which can display several different file types, within the confines of your own window. Although this program causes your entire output window to be used for the display, it can easily be adapted to reduce the size of the document window and leave space for other components.

Initialisation
The first step is some necessary initialisation:

code format="bb4w" INSTALL @lib$+"WINLIB5" SYS "LoadLibrary", "ATL.DLL" TO atl% SYS "GetProcAddress", atl%, "AtlAxWinInit" TO `AtlAxWinInit` SYS `AtlAxWinInit` code

Creating a menu
In this example application a simple menu is created, giving the option to open or close the file to be viewed, or to exit the program. You may want to select the file in a different way.

code format="bb4w" SYS "CreatePopupMenu" TO hfile% SYS "AppendMenu", hfile%, 0, 101, "&Open"+CHR$9+"Ctrl+O" SYS "AppendMenu", hfile%, 0, 102, "&Close" SYS "AppendMenu", hfile%, 0, 103, "E&xit" SYS "CreateMenu" TO hmenu% SYS "AppendMenu", hmenu%, 16, hfile%, "&File" SYS "SetMenu", @hwnd%, hmenu% SYS "DrawMenuBar", @hwnd% code

Event handling
The code below handles menu selection and window-resizing events. The latter is to ensure that if your main window is resized by the user, the viewer window is resized to suit:

code format="bb4w" ON SYS Click% = @wparam% : RETURN ON MOVE PROCmove(@msg%, @wparam%, @lparam%) : RETURN *ESC OFF Click% = 0 hATL% = 0 REPEAT select% = INKEY(1) IF select% = -1 SWAP select%,Click% CASE select% OF         WHEN 101, 15: hATL% = FNopen(hATL%) WHEN 102: IF hATL% PROC_closewindow(hATL%) : hATL%=0 WHEN 103: QUIT ENDCASE UNTIL FALSE END code Note that the statement is only included for neatness; it can never be reached. The global variable **hATL%** is the window handle of the viewer window.

Opening the file
The code below displays a file selector dialogue, and opens the selected file (if any):

code format="bb4w" DEF FNopen(hw%) LOCAL fs{}, rc{}, fp%, ff$, res% DIM fs{lStructSize%, hwndOwner%, hInstance%, lpstrFilter%, \ \     lpstrCustomFilter%, nMaxCustFilter%, nFilterIndex%, \ \     lpstrFile%, nMaxFile%, lpstrFileTitle%, \ \     nMaxFileTitle%, lpstrInitialDir%, lpstrTitle%, \ \     flags%, nFileOffset{l&,h&}, nFileExtension{l&,h&}, \ \     lpstrDefExt%, lCustData%, lpfnHook%, lpTemplateName%} DIM fp% LOCAL 255 ff$ = "PDF files"+CHR$0+"*.PDF"+CHR$0+"HTML files"+CHR$0+"*.HTM;*.HTML"+CHR$0+ \ \    "Text files"+CHR$0+"*.TXT"+CHR$0+"Image files"+CHR$0+"*.JPG;*.GIF;*.PNG"+ \ \    CHR$0+CHR$0 fs.lStructSize% = DIM(fs{}) fs.hwndOwner% = @hwnd% fs.lpstrFilter% = !^ff$ fs.lpstrFile% = fp% fs.nMaxFile% = 256 fs.flags% = 6 SYS "GetOpenFileName", fs{} TO res% IF res% = 0 THEN = 0 IF hw% PROC_closewindow(hw%) DIM rc{l%,t%,r%,b%} SYS "GetClientRect", @hwnd%, rc{} = FN_createwindow("AtlAxWin", $$fp%, 0, 0, rc.r%-rc.l%, rc.b%-rc.t%, 0, &200000, 0) code If the file is successfully opened the function returns the handle of the viewer window. If you want the viewer window to occupy less that the full area of your output window you can determine the dimensions in a way other than **SYS "GetClientRect"**.

Window resizing
The code below simply resizes the viewer window to match the client area of your output window. Again you may wish to determine the dimensions differently:

code format="bb4w" DEF PROCmove(M%, W%, L%) IF M% = 5 IF hATL% SYS "SetWindowPos", hATL%, 0, 0, 0, L% AND &FFFF, L% >>> 16, 6 ENDPROC code

For more information on the Active Template Library consult Microsoft's [|ATL Reference].