=====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 [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwine.html#opendoc|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:\\ \\ INSTALL @lib$+"WINLIB5" SYS "LoadLibrary", "ATL.DLL" TO atl% SYS "GetProcAddress", atl%, "AtlAxWinInit" TO `AtlAxWinInit` SYS `AtlAxWinInit` \\ ==== 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.\\ \\ 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% \\ ==== 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:\\ \\ 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 Note that the "END" 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):\\ \\ 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) 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:\\ \\ DEF PROCmove(M%, W%, L%) IF M% = 5 IF hATL% SYS "SetWindowPos", hATL%, 0, 0, 0, L% AND &FFFF, L% >>> 16, 6 ENDPROC \\ For more information on the Active Template Library consult Microsoft's [[http://msdn2.microsoft.com/en-us/library/t9adwcde(VS.80).aspx|ATL Reference]].