User Tools

Site Tools


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.


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
          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

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

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

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
using_20an_20atl_20container_20control.txt · Last modified: 2018/04/15 19:54 by tbest3112