home *** CD-ROM | disk | FTP | other *** search
/ BUG 4 / BUGCD1997_05.BIN / aplic / clip4win / clip4win.exe / C4W30E.HUF / SOURCE / APPOLD.PRG < prev    next >
Text File  |  1995-05-03  |  15KB  |  442 lines

  1. ////////////////////////////
  2. //
  3. //    Clip-4-Win "minimum application" template
  4. //
  5. //    Copyright (C) 1994 Skelton Software, Kendal Cottage, Hillam, Leeds, UK.
  6. //    All Rights Reserved.
  7. //
  8. //    These are typical things you want in your application.
  9. //
  10. //    INSTRUCTIONS:
  11. //    =============
  12. //
  13. //        Look for comments starting "//TBD:" - these tell you
  14. //        things you need to know/change/do.
  15. //
  16. //TBD:    Copy this file (APP.PRG), APP.DEF and APP.RMK to <YourName>.*.
  17. //
  18. //        Change the name and description in APP.DEF.
  19. //        Change the RMK file to use <YourName> instead of APP.
  20. //        Note: obvious choices are which linker you use
  21. //            (Blinker, OptLink, MS Link), and which resource
  22. //            tool, if any (Borland Resource Workshop, MS AppStudio,
  23. //            the old MS DlgEdit).
  24. //        Keep following the "//TBD:" comments below.
  25. //
  26. //TBD:    You need to change the menus to suit your application.
  27. //
  28. //        Many menu choices need to start something that needs
  29. //        to carry on independently of other activities.  You
  30. //        probably want to use AddHandler() to make this happen.
  31. //        See demomult.prg for a program that does a lot of this.
  32. //
  33. //TBD:    Decide whether you want a toolbar.
  34. //
  35. //        If not, remove the #define WANT_TOOLBAR below.
  36. //        Otherwise, fill in bitmap etc. details in ToolbarSetup().
  37. //
  38. //TBD:    Data entry screens should often be dialogs.
  39. //
  40. //        See e.g. dialog.prg, users.prg, and addmgr\.
  41. //
  42. //TBD:    For browsers you can use:
  43. //        TBrowse (e.g. see demomult.prg, function DoBrowse().)
  44. //        a Clip-4-Win browser (e.g. source\dbrowse\*.prg,
  45. //                    source\addmgr\browse.prg)
  46. //        or a listbox (see listbox.prg).
  47. //
  48. ////////////////////////////
  49.  
  50.  
  51. //TBD: You may want some of these (where XXX is e.g. ALL, RESOURCE, or LB):
  52. //    #define    WIN_WANT_XXX
  53. #include "windows.ch"
  54. #define    NO_C4WCLASS
  55. #include "commands.ch"
  56.  
  57.  
  58. //#define RESOURCE            //TBD: define if using a res. compiler
  59. #define    WANT_TOOLBAR            //TBD: decide if you want one
  60.  
  61. #ifdef    WANT_TOOLBAR
  62.   #define    TB_HEIGHT    31    //TBD: depends on your bitmaps
  63.   #define    ID_TOOLBAR    1000
  64.   #define    ID_CLIENT    1001
  65. #else
  66.   #define    TB_HEIGHT    0
  67.   #define    ID_CLIENT    1001
  68. #endif    // WANT_TOOLBAR
  69.  
  70.  
  71. //───── manifest constants for GetClientRect() and GetDIBRect() arrays
  72. //───── note that since Top and Left are always 0, they are unused
  73. #define W_RIGHT  3
  74. #define W_BOTTOM 4
  75.  
  76. //───── manifest constants for RGB() color combinations
  77. #define C_RED        RGB(255,0,0)
  78. #define C_GREEN      RGB(0,255,0)
  79. #define C_BLUE       RGB(0,0,255)
  80. #define C_MAGENTA    RGB(255,0,255)
  81. #define C_BLACK      RGB(0,0,0)
  82. #define C_WHITE      RGB(255,255,255)
  83.  
  84.  
  85. static    cAppName := "Clip-4-Win"    //TBD: your app name here
  86. static    hFrameWnd            // top-most (frame) window
  87. static    hMainWnd            // main (client) window
  88.  
  89.  
  90. function main()
  91. local    hMenu, nEvent, hWnd, hCurrWnd, hTBWnd, aRect
  92.  
  93. set scoreboard off
  94. set confirm on
  95. SetColor("n/w,+w/n,+w,+w,+w/n")        //TBD: you might like to change these
  96.  
  97. /*
  98.  *  Set up the outermost window as the frame window, with the "main"
  99.  *  window actually a child sized to fit the area left after the toolbar
  100.  *  (if there is one).
  101.  */
  102. //TBD: you may want to specify more params to WinSetup()
  103. hFrameWnd := WinSetup(cAppName, "<your title here>")    //TBD: your title
  104. HideCaret(hFrameWnd)
  105. hMenu := MenuSetup()
  106. #ifdef    WANT_TOOLBAR
  107. hTBWnd := ToolbarSetup(hFrameWnd, hMenu)
  108. #endif    // WANT_TOOLBAR
  109. aRect := GetClientRect(hFrameWnd)
  110. hMainWnd := CreateWindow(cAppName, "", WS_CHILD + WS_VISIBLE, ;
  111.              0, TB_HEIGHT, aRect[W_RIGHT], aRect[W_BOTTOM] - TB_HEIGHT,;
  112.              hFrameWnd, ID_CLIENT)
  113. HideCaret(hMainWnd)
  114. AddHandler(hFrameWnd, {|nEvent| FrameEvent(nEvent, hTBWnd, hMainWnd)})
  115.  
  116. /*
  117.  *  The C4W_AutoClose() function allows us to make the user confirm their
  118.  *  decision to quit the app, even if they try to close the window
  119.  *  with ALT-F4 (or via the System menu).  It will cause the EVENT_CLOSE
  120.  *  event to be generated, which we can then react to (see below)
  121.  */
  122. C4W_AutoClose(.f.)        // disable auto-closing of Windows
  123.  
  124. /*
  125.  *  You're almost certain to need SetHandleCount( <n> ) !!
  126.  */
  127. SetHandleCount(60)        //TBD: make sure you have enough handles
  128.  
  129. Ctl3d(.t.)            // default to 3D controls and dialogs
  130.  
  131. /*
  132.  *  Here is the main event loop.
  133.  *
  134.  *  Your aim is to process any relevant events and return here.
  135.  *  Generally you do this simply by letting menu (or toolbar) selections
  136.  *  result in the appropriate code block being run.  The calls to
  137.  *  MenuSetup() and ToolbarSetup() above are enough to arrange for the
  138.  *  loop below to automatically handle the menu/toolbar selections.
  139.  */
  140.  
  141. do while .t.
  142.    do while (nEvent := ChkEvent()) == EVENT_NONE
  143.       // "background" processing could go here
  144.    enddo
  145.  
  146.    // almost all events get passed on to the appropriate
  147.    // handler(s) here
  148.    HandleEvent(nEvent)    // give the event to the right handler
  149.  
  150.    // a few special events are worth doing here
  151.    do case
  152.    case nEvent == EVENT_CLOSE
  153.       hWnd := _LasthWnd()
  154.       if hWnd != hFrameWnd
  155.          /*
  156.           *  The user wants to destroy the window.
  157.           *  You may not want to destroy it, but here's how!
  158.           */
  159.          DestroyWindow(hWnd)
  160.          SetFocus(hMainWnd)
  161.       endif
  162.    case nEvent == EVENT_QUIT
  163.       Ctl3d(.f.)          // stop using 3D controls
  164.       if IsWindow(hFrameWnd)
  165.          DestroyWindow(hFrameWnd)
  166.       endif
  167.       quit
  168.    endcase
  169. enddo
  170.  
  171. return 0
  172.  
  173.  
  174. static procedure FrameEvent(nEvent, hTBWnd, hWnd)
  175. local aRect, nW, nH
  176. do case
  177. case nEvent == EVENT_WINSIZE
  178.    aRect := GetClientRect(hFrameWnd)
  179.    nW := aRect[W_RIGHT]        // same as _LastLolParam()
  180.    nH := aRect[W_BOTTOM]    // same as _LastHilParam()
  181. #ifdef    WANT_TOOLBAR
  182.    MoveWindow(hTBWnd, 0, 0, nW, TB_HEIGHT, .t.)
  183. #endif    // WANT_TOOLBAR
  184.    MoveWindow(hWnd, 0, TB_HEIGHT, nW, nH - TB_HEIGHT, .f.)
  185. case nEvent == EVENT_SETFOCUS
  186.    SetFocus(hWnd)        //TBD: you might want to set focus elsewhere
  187. case nEvent == EVENT_CLOSE
  188.    // user wants to destroy the main (frame) window
  189.    // - maybe exit
  190.    DoExit()
  191. endcase
  192. return
  193.  
  194.  
  195. static procedure DoAbout()
  196. MessageBox( , "Written by John Skelton.", "Info", MB_OK)    //TBD: change
  197. return
  198.  
  199.  
  200. static procedure DoExit()
  201. //TBD:    You may want to change this.
  202. //───── Note that MessageBox() returns a value based on the I.D. of
  203. //───── the selected item, all of which have corresponding ID* manifest
  204. //───── constants in the WINDOWS.CH header file
  205. if MessageBox(0, "Are you sure you want to exit?", ;
  206.          cAppName, MB_OKCANCEL + MB_ICONQUESTION) == IDOK
  207.    Ctl3d(.f.)          // stop using 3D controls
  208.    if IsWindow(hFrameWnd)
  209.       DestroyWindow(hFrameWnd)
  210.    endif
  211.    quit
  212. endif
  213. return
  214.  
  215.  
  216. static procedure DoOpen()
  217. //TBD:    This is just an example.  See e.g. demomult.prg.
  218. local    cFile := GetOpenFileName(, "*.dbf", "Select a database")
  219. if cFile != NIL
  220.    //TBD: here you do something with the file.
  221. endif
  222. return
  223.  
  224.  
  225. static procedure DoClear()
  226. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  227. return
  228.  
  229.  
  230. static procedure DoRun()
  231. //TBD:    This is just an example.
  232. local cFile := GetOpenFileName(, "*.exe;*.com;*.bat", "Run", ;
  233.                    { {"programs", "*.exe;*.com;*.bat"} } )
  234. local hCursor
  235. local hOldcursor
  236. if cFile <> NIL
  237.    hCursor := LoadCursor(, IDC_WAIT)
  238.    hOldcursor := SetCursor(hCursor)
  239.    WinExec(cFile)
  240.    SetCursor(hOldcursor)   // restore previous cursor
  241. endif
  242. return
  243.  
  244.  
  245. static procedure DoSave()
  246. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  247. //TBD:    You may find GetSaveFileName() useful.
  248. return
  249.  
  250.  
  251. static procedure DoSaveAs()
  252. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  253. //TBD:    You may find GetSaveFileName() useful.
  254. return
  255.  
  256. static procedure DoPrint()
  257. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  258. //TBD:    You may find GetPrintDC() or PrintDlg() useful.
  259. return
  260.  
  261. static procedure DoCut()
  262. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  263. return
  264.  
  265. static procedure DoCopy()
  266. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  267. return
  268.  
  269. static procedure DoPaste()
  270. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  271. return
  272.  
  273. static procedure DoYourMenu()
  274. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  275. return
  276.  
  277. static procedure DoGoesHere()
  278. MessageBox( , "Your code goes here", "Info", MB_OK)    //TBD: change
  279. return
  280.  
  281.  
  282. static function MenuSetup()
  283. local    hWnd := SelectWindow(), hMenu, hPopupMenu
  284.  
  285. //TBD:    Change these menus...
  286.  
  287. //───── Note the grayed out entries (search for GRAYED).
  288. //───── Ampersand (&) indicates the trigger letter (accelerator key).
  289. //───── You don't need to use ID <x>, unless you later want to refer to the
  290. //      menu item - e.g. to enable/disable/gray/check/uncheck it.
  291.  
  292. MENU hMenu IN hWnd
  293.     POPUP "&File"  // ID "file"
  294.         MENUITEM "&Open..."     ACTION DoOpen()           ID "open"
  295.         MENUITEM "&Clear"       ACTION DoClear()  GRAYED  // ID "clear"
  296.         MENUITEM "&Run..."      ACTION DoRun()            // ID "run"
  297.         MENUITEM "&Save"        ACTION DoSave()   GRAYED  ID "save"
  298.         MENUITEM "Save &As..."  ACTION DoSaveAs() GRAYED  ID "saveas"
  299.         MENUITEM SEPARATOR
  300.         MENUITEM "&Print..."    ACTION DoPrint()          ID "print"
  301.         MENUITEM SEPARATOR
  302. // Use this if you want to be prompted:
  303. //      MENUITEM "E&xit"        ACTION DoExit()           ID "exit"
  304.         MENUITEM "E&xit"        ACTION PostQuitMessage(0) ID "exit"
  305.     ENDPOPUP
  306.     POPUP "&Edit"  // ID "edit"
  307.         MENUITEM "Cu&t"         ACTION DoCut()    // ID "cut"
  308.         MENUITEM "&Copy"        ACTION DoCopy()   // ID "copy"
  309.         MENUITEM "&Paste"       ACTION DoPaste()  // ID "paste"
  310.     ENDPOPUP
  311.     POPUP "&Demo"  // ID "demo"
  312.         MENUITEM "&Your menu"  ACTION DoYourMenu()  // ID "demo_1"
  313.         MENUITEM "&Goes here"  ACTION DoGoesHere()  // ID "demo_2"
  314.     ENDPOPUP
  315.     POPUP "&Help"  // ID "help"
  316.         MENUITEM "&About"  ACTION DoAbout()  ID "about"
  317.     ENDPOPUP
  318. ENDMENU
  319.  
  320. /*
  321.  *  These are the close equivalents of the above:
  322.  */
  323. #ifdef    NOTDEF
  324. if (hMenu := GetMenu(hWnd)) != nil
  325.    DestroyMenu(hMenu)
  326. endif
  327.  
  328. hMenu = CreateMenu()
  329. hPopupMenu = CreatePopupMenu()
  330. AppendMenu(hMenu, "file", MF_ENABLED + MF_POPUP, "&File", hPopupMenu)
  331. AppendMenu(hPopupMenu, "open", MF_ENABLED + MF_STRING, "&Open...", {|| DoOpen()})
  332. AppendMenu(hPopupMenu, "clear", MF_GRAYED + MF_STRING, "&Clear", {|| DoClear()})
  333. AppendMenu(hPopupMenu, "run", MF_ENABLED + MF_STRING, "&Run...", {|| DoRun()})
  334. AppendMenu(hPopupMenu, "save", MF_GRAYED + MF_STRING, "&Save", {|| DoSave()})
  335. AppendMenu(hPopupMenu, "saveas", MF_GRAYED + MF_STRING, "Save &As...", {|| DoSaveAs()})
  336. AppendMenu(hPopupMenu, "", MF_SEPARATOR)
  337. AppendMenu(hPopupMenu, "print", MF_ENABLED + MF_STRING, "&Print...", {|| DoPrint()})
  338. AppendMenu(hPopupMenu, "", MF_SEPARATOR)
  339. AppendMenu(hPopupMenu, "exit", MF_ENABLED + MF_STRING, "E&xit", {|| DoExit()})
  340. hPopupMenu = CreatePopupMenu()
  341. AppendMenu(hMenu, "edit", MF_ENABLED + MF_POPUP, "&Edit", hPopupMenu)
  342. AppendMenu(hPopupMenu, "cut",   MF_ENABLED + MF_STRING, "Cu&t",  {|c| DoCut()})
  343. AppendMenu(hPopupMenu, "copy",  MF_ENABLED + MF_STRING, "&Copy", {|c| DoCopy()})
  344. AppendMenu(hPopupMenu, "paste", MF_ENABLED + MF_STRING, "&Paste", {|| DoPaste()})
  345. hPopupMenu = CreatePopupMenu()
  346. AppendMenu(hMenu, "demo", MF_ENABLED + MF_POPUP, "&Demo", hPopupMenu)
  347. AppendMenu(hPopupMenu, "demo_1", MF_ENABLED + MF_STRING, "&Your menu", {|c| DoYourMenu()})
  348. AppendMenu(hPopupMenu, "demo_2", MF_ENABLED + MF_STRING, "&Goes here", {|c| DoGoesHere()})
  349. hPopupMenu = CreatePopupMenu()
  350. AppendMenu(hMenu, "help", MF_ENABLED + MF_POPUP, "&Help", hPopupMenu)
  351. AppendMenu(hPopupMenu, "about", MF_ENABLED + MF_STRING, "&About", {|| DoAbout()})
  352. SetMenu(hWnd, hMenu)
  353. #endif    // NOTDEF
  354. return hMenu
  355.  
  356.  
  357. #ifdef    WANT_TOOLBAR
  358.  
  359. static function ToolbarSetup(hWnd, hMenu)
  360. //TBD: Whether using resources or not, you usually want toolbar buttons
  361. //    to do something that is in a menu, which is the way toolbar.prg
  362. //    is written (it sends WM_COMMAND messages, with the right params
  363. //    to produce EVENT_MENU events).  You can easily change this, if
  364. //    you wish.
  365. #ifdef    RESOURCE
  366. //TBD: put bitmaps in your resource file(s), and load them here
  367. //TBD: set the bitmap id's/names, change the co-ordinates
  368. //TBD: if using GetMenuId(), make sure you used that ID in your menu!
  369. local    aButtons :=                            ;
  370. { {10, 4, 25, 22, LoadBitmap( , IDB_OPEN), GetMenuId(hMenu, "open")},    ;
  371.   {36, 4, 25, 22, LoadBitmap( , IDB_PRINT), GetMenuId(hMenu, "print")},    ;
  372.   {62, 4, 25, 22, LoadBitmap( , IDB_BROWSE), GetMenuId(hMenu, "browse")},    ;
  373.   {92, 4, 25, 22, LoadBitmap( , IDB_EXIT), GetMenuId(hMenu, "exit")},    ;
  374.   {122, 4, 25, 22, LoadBitmap( , IDB_ABOUT), GetMenuId(hMenu, "about")} }
  375. #else
  376. //TBD: read the appropriate bitmaps here
  377. //TBD: set the bitmap names, change the co-ordinates
  378. //TBD: if using GetMenuId(), make sure you used that ID in your menu!
  379. local    aButtons :=                            ;
  380. { {10, 4, 25, 22, ReadDIB("open1.bmp"), GetMenuId(hMenu, "open")},    ;
  381.   {36, 4, 25, 22, ReadDIB("print1.bmp"), GetMenuId(hMenu, "print")},    ;
  382.   {62, 4, 25, 22, ReadDIB("browse1.bmp"), GetMenuId(hMenu, "browse")},    ;
  383.   {92, 4, 25, 22, ReadDIB("exit1.bmp"), GetMenuId(hMenu, "exit")},    ;
  384.   {122, 4, 25, 22, ReadDIB("help1.bmp"), GetMenuId(hMenu, "about")} }
  385. #endif    // RESOURCE
  386. local    aRect, hTBWnd
  387.  
  388. /*
  389.  *  This sample puts the toolbar at the top of the window's
  390.  *  client area.  A child window is created to fill the area
  391.  *  left.  The user doesn't know (or care) the "childclient" exists,
  392.  *  so just make it fill the area not used by the toolbar.  Of
  393.  *  course, this means changing its size if the main window changes
  394.  *  size (msg WM_SIZE).  The toolbar size needs to change as well
  395.  *  (just the width in this example).
  396.  *
  397.  *  This same technique can be useful at other times, e.g. the child
  398.  *  might be a multi-line edit control.
  399.  *
  400.  *  If you have a status bar, the easiest way to handle it is to
  401.  *  make it another window (with no special border, no title bar,
  402.  *  etc., and using WS_CHILD + WS_VISIBLE), put it at the bottom
  403.  *  of the frame window, and reduce the child client's window height
  404.  *  by the height of the status bar.
  405.  *  (Yes, you do get extra windows.  Don't worry.)
  406.  */
  407.  
  408. aRect = GetClientRect(hWnd)
  409. hTBWnd = ToolBar(hWnd, 0, 0, aRect[3], TB_HEIGHT, aButtons, ID_TOOLBAR)
  410. return hTBWnd
  411.  
  412. #endif    // WANT_TOOLBAR
  413.  
  414.  
  415.  
  416. static procedure Ctl3d(lOn)
  417. static    hLibCtl3d
  418. local    hInst := _GetInstance(), cDLL
  419.  
  420. if lOn .and. hLibCtl3d == nil
  421.    hLibCtl3d := LoadLibrary("ctl3d.dll")
  422.    if hLibCtl3d == nil .or. hLibCtl3d < 32
  423.       MessageBox( , "Unable to find CTL3D.DLL", "Error", MB_ICONSTOP)
  424.       hLibCtl3d := nil
  425.    else
  426.       cDLL := GetProcAddress(hLibCtl3d, "Ctl3dRegister", "Pascal", ;
  427.                  "void", "int")
  428.       CallDLL(cDLL, hInst)
  429.       cDLL := GetProcAddress(hLibCtl3d, "Ctl3dAutoSubclass", "Pascal",;
  430.                  "void", "int")
  431.       CallDLL(cDLL, hInst)
  432.    endif
  433. elseif !lOn .and. hLibCtl3d != nil
  434.    cDLL := GetProcAddress(hLibCtl3d, "Ctl3dUnregister", "Pascal",   ;
  435.               "void", "int")
  436.    CallDLL(cDLL, hInst)
  437.    FreeLibrary(hLibCtl3d)
  438.    hLibCtl3d := nil
  439. endif
  440. return
  441.  
  442.