home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BUG 4
/
BUGCD1997_05.BIN
/
aplic
/
clip4win
/
clip4win.exe
/
C4W30E.HUF
/
SOURCE
/
APPOLD.PRG
< prev
next >
Wrap
Text File
|
1995-05-03
|
15KB
|
442 lines
////////////////////////////
//
// Clip-4-Win "minimum application" template
//
// Copyright (C) 1994 Skelton Software, Kendal Cottage, Hillam, Leeds, UK.
// All Rights Reserved.
//
// These are typical things you want in your application.
//
// INSTRUCTIONS:
// =============
//
// Look for comments starting "//TBD:" - these tell you
// things you need to know/change/do.
//
//TBD: Copy this file (APP.PRG), APP.DEF and APP.RMK to <YourName>.*.
//
// Change the name and description in APP.DEF.
// Change the RMK file to use <YourName> instead of APP.
// Note: obvious choices are which linker you use
// (Blinker, OptLink, MS Link), and which resource
// tool, if any (Borland Resource Workshop, MS AppStudio,
// the old MS DlgEdit).
// Keep following the "//TBD:" comments below.
//
//TBD: You need to change the menus to suit your application.
//
// Many menu choices need to start something that needs
// to carry on independently of other activities. You
// probably want to use AddHandler() to make this happen.
// See demomult.prg for a program that does a lot of this.
//
//TBD: Decide whether you want a toolbar.
//
// If not, remove the #define WANT_TOOLBAR below.
// Otherwise, fill in bitmap etc. details in ToolbarSetup().
//
//TBD: Data entry screens should often be dialogs.
//
// See e.g. dialog.prg, users.prg, and addmgr\.
//
//TBD: For browsers you can use:
// TBrowse (e.g. see demomult.prg, function DoBrowse().)
// a Clip-4-Win browser (e.g. source\dbrowse\*.prg,
// source\addmgr\browse.prg)
// or a listbox (see listbox.prg).
//
////////////////////////////
//TBD: You may want some of these (where XXX is e.g. ALL, RESOURCE, or LB):
// #define WIN_WANT_XXX
#include "windows.ch"
#define NO_C4WCLASS
#include "commands.ch"
//#define RESOURCE //TBD: define if using a res. compiler
#define WANT_TOOLBAR //TBD: decide if you want one
#ifdef WANT_TOOLBAR
#define TB_HEIGHT 31 //TBD: depends on your bitmaps
#define ID_TOOLBAR 1000
#define ID_CLIENT 1001
#else
#define TB_HEIGHT 0
#define ID_CLIENT 1001
#endif // WANT_TOOLBAR
//───── manifest constants for GetClientRect() and GetDIBRect() arrays
//───── note that since Top and Left are always 0, they are unused
#define W_RIGHT 3
#define W_BOTTOM 4
//───── manifest constants for RGB() color combinations
#define C_RED RGB(255,0,0)
#define C_GREEN RGB(0,255,0)
#define C_BLUE RGB(0,0,255)
#define C_MAGENTA RGB(255,0,255)
#define C_BLACK RGB(0,0,0)
#define C_WHITE RGB(255,255,255)
static cAppName := "Clip-4-Win" //TBD: your app name here
static hFrameWnd // top-most (frame) window
static hMainWnd // main (client) window
function main()
local hMenu, nEvent, hWnd, hCurrWnd, hTBWnd, aRect
set scoreboard off
set confirm on
SetColor("n/w,+w/n,+w,+w,+w/n") //TBD: you might like to change these
/*
* Set up the outermost window as the frame window, with the "main"
* window actually a child sized to fit the area left after the toolbar
* (if there is one).
*/
//TBD: you may want to specify more params to WinSetup()
hFrameWnd := WinSetup(cAppName, "<your title here>") //TBD: your title
HideCaret(hFrameWnd)
hMenu := MenuSetup()
#ifdef WANT_TOOLBAR
hTBWnd := ToolbarSetup(hFrameWnd, hMenu)
#endif // WANT_TOOLBAR
aRect := GetClientRect(hFrameWnd)
hMainWnd := CreateWindow(cAppName, "", WS_CHILD + WS_VISIBLE, ;
0, TB_HEIGHT, aRect[W_RIGHT], aRect[W_BOTTOM] - TB_HEIGHT,;
hFrameWnd, ID_CLIENT)
HideCaret(hMainWnd)
AddHandler(hFrameWnd, {|nEvent| FrameEvent(nEvent, hTBWnd, hMainWnd)})
/*
* The C4W_AutoClose() function allows us to make the user confirm their
* decision to quit the app, even if they try to close the window
* with ALT-F4 (or via the System menu). It will cause the EVENT_CLOSE
* event to be generated, which we can then react to (see below)
*/
C4W_AutoClose(.f.) // disable auto-closing of Windows
/*
* You're almost certain to need SetHandleCount( <n> ) !!
*/
SetHandleCount(60) //TBD: make sure you have enough handles
Ctl3d(.t.) // default to 3D controls and dialogs
/*
* Here is the main event loop.
*
* Your aim is to process any relevant events and return here.
* Generally you do this simply by letting menu (or toolbar) selections
* result in the appropriate code block being run. The calls to
* MenuSetup() and ToolbarSetup() above are enough to arrange for the
* loop below to automatically handle the menu/toolbar selections.
*/
do while .t.
do while (nEvent := ChkEvent()) == EVENT_NONE
// "background" processing could go here
enddo
// almost all events get passed on to the appropriate
// handler(s) here
HandleEvent(nEvent) // give the event to the right handler
// a few special events are worth doing here
do case
case nEvent == EVENT_CLOSE
hWnd := _LasthWnd()
if hWnd != hFrameWnd
/*
* The user wants to destroy the window.
* You may not want to destroy it, but here's how!
*/
DestroyWindow(hWnd)
SetFocus(hMainWnd)
endif
case nEvent == EVENT_QUIT
Ctl3d(.f.) // stop using 3D controls
if IsWindow(hFrameWnd)
DestroyWindow(hFrameWnd)
endif
quit
endcase
enddo
return 0
static procedure FrameEvent(nEvent, hTBWnd, hWnd)
local aRect, nW, nH
do case
case nEvent == EVENT_WINSIZE
aRect := GetClientRect(hFrameWnd)
nW := aRect[W_RIGHT] // same as _LastLolParam()
nH := aRect[W_BOTTOM] // same as _LastHilParam()
#ifdef WANT_TOOLBAR
MoveWindow(hTBWnd, 0, 0, nW, TB_HEIGHT, .t.)
#endif // WANT_TOOLBAR
MoveWindow(hWnd, 0, TB_HEIGHT, nW, nH - TB_HEIGHT, .f.)
case nEvent == EVENT_SETFOCUS
SetFocus(hWnd) //TBD: you might want to set focus elsewhere
case nEvent == EVENT_CLOSE
// user wants to destroy the main (frame) window
// - maybe exit
DoExit()
endcase
return
static procedure DoAbout()
MessageBox( , "Written by John Skelton.", "Info", MB_OK) //TBD: change
return
static procedure DoExit()
//TBD: You may want to change this.
//───── Note that MessageBox() returns a value based on the I.D. of
//───── the selected item, all of which have corresponding ID* manifest
//───── constants in the WINDOWS.CH header file
if MessageBox(0, "Are you sure you want to exit?", ;
cAppName, MB_OKCANCEL + MB_ICONQUESTION) == IDOK
Ctl3d(.f.) // stop using 3D controls
if IsWindow(hFrameWnd)
DestroyWindow(hFrameWnd)
endif
quit
endif
return
static procedure DoOpen()
//TBD: This is just an example. See e.g. demomult.prg.
local cFile := GetOpenFileName(, "*.dbf", "Select a database")
if cFile != NIL
//TBD: here you do something with the file.
endif
return
static procedure DoClear()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
return
static procedure DoRun()
//TBD: This is just an example.
local cFile := GetOpenFileName(, "*.exe;*.com;*.bat", "Run", ;
{ {"programs", "*.exe;*.com;*.bat"} } )
local hCursor
local hOldcursor
if cFile <> NIL
hCursor := LoadCursor(, IDC_WAIT)
hOldcursor := SetCursor(hCursor)
WinExec(cFile)
SetCursor(hOldcursor) // restore previous cursor
endif
return
static procedure DoSave()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
//TBD: You may find GetSaveFileName() useful.
return
static procedure DoSaveAs()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
//TBD: You may find GetSaveFileName() useful.
return
static procedure DoPrint()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
//TBD: You may find GetPrintDC() or PrintDlg() useful.
return
static procedure DoCut()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
return
static procedure DoCopy()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
return
static procedure DoPaste()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
return
static procedure DoYourMenu()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
return
static procedure DoGoesHere()
MessageBox( , "Your code goes here", "Info", MB_OK) //TBD: change
return
static function MenuSetup()
local hWnd := SelectWindow(), hMenu, hPopupMenu
//TBD: Change these menus...
//───── Note the grayed out entries (search for GRAYED).
//───── Ampersand (&) indicates the trigger letter (accelerator key).
//───── You don't need to use ID <x>, unless you later want to refer to the
// menu item - e.g. to enable/disable/gray/check/uncheck it.
MENU hMenu IN hWnd
POPUP "&File" // ID "file"
MENUITEM "&Open..." ACTION DoOpen() ID "open"
MENUITEM "&Clear" ACTION DoClear() GRAYED // ID "clear"
MENUITEM "&Run..." ACTION DoRun() // ID "run"
MENUITEM "&Save" ACTION DoSave() GRAYED ID "save"
MENUITEM "Save &As..." ACTION DoSaveAs() GRAYED ID "saveas"
MENUITEM SEPARATOR
MENUITEM "&Print..." ACTION DoPrint() ID "print"
MENUITEM SEPARATOR
// Use this if you want to be prompted:
// MENUITEM "E&xit" ACTION DoExit() ID "exit"
MENUITEM "E&xit" ACTION PostQuitMessage(0) ID "exit"
ENDPOPUP
POPUP "&Edit" // ID "edit"
MENUITEM "Cu&t" ACTION DoCut() // ID "cut"
MENUITEM "&Copy" ACTION DoCopy() // ID "copy"
MENUITEM "&Paste" ACTION DoPaste() // ID "paste"
ENDPOPUP
POPUP "&Demo" // ID "demo"
MENUITEM "&Your menu" ACTION DoYourMenu() // ID "demo_1"
MENUITEM "&Goes here" ACTION DoGoesHere() // ID "demo_2"
ENDPOPUP
POPUP "&Help" // ID "help"
MENUITEM "&About" ACTION DoAbout() ID "about"
ENDPOPUP
ENDMENU
/*
* These are the close equivalents of the above:
*/
#ifdef NOTDEF
if (hMenu := GetMenu(hWnd)) != nil
DestroyMenu(hMenu)
endif
hMenu = CreateMenu()
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "file", MF_ENABLED + MF_POPUP, "&File", hPopupMenu)
AppendMenu(hPopupMenu, "open", MF_ENABLED + MF_STRING, "&Open...", {|| DoOpen()})
AppendMenu(hPopupMenu, "clear", MF_GRAYED + MF_STRING, "&Clear", {|| DoClear()})
AppendMenu(hPopupMenu, "run", MF_ENABLED + MF_STRING, "&Run...", {|| DoRun()})
AppendMenu(hPopupMenu, "save", MF_GRAYED + MF_STRING, "&Save", {|| DoSave()})
AppendMenu(hPopupMenu, "saveas", MF_GRAYED + MF_STRING, "Save &As...", {|| DoSaveAs()})
AppendMenu(hPopupMenu, "", MF_SEPARATOR)
AppendMenu(hPopupMenu, "print", MF_ENABLED + MF_STRING, "&Print...", {|| DoPrint()})
AppendMenu(hPopupMenu, "", MF_SEPARATOR)
AppendMenu(hPopupMenu, "exit", MF_ENABLED + MF_STRING, "E&xit", {|| DoExit()})
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "edit", MF_ENABLED + MF_POPUP, "&Edit", hPopupMenu)
AppendMenu(hPopupMenu, "cut", MF_ENABLED + MF_STRING, "Cu&t", {|c| DoCut()})
AppendMenu(hPopupMenu, "copy", MF_ENABLED + MF_STRING, "&Copy", {|c| DoCopy()})
AppendMenu(hPopupMenu, "paste", MF_ENABLED + MF_STRING, "&Paste", {|| DoPaste()})
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "demo", MF_ENABLED + MF_POPUP, "&Demo", hPopupMenu)
AppendMenu(hPopupMenu, "demo_1", MF_ENABLED + MF_STRING, "&Your menu", {|c| DoYourMenu()})
AppendMenu(hPopupMenu, "demo_2", MF_ENABLED + MF_STRING, "&Goes here", {|c| DoGoesHere()})
hPopupMenu = CreatePopupMenu()
AppendMenu(hMenu, "help", MF_ENABLED + MF_POPUP, "&Help", hPopupMenu)
AppendMenu(hPopupMenu, "about", MF_ENABLED + MF_STRING, "&About", {|| DoAbout()})
SetMenu(hWnd, hMenu)
#endif // NOTDEF
return hMenu
#ifdef WANT_TOOLBAR
static function ToolbarSetup(hWnd, hMenu)
//TBD: Whether using resources or not, you usually want toolbar buttons
// to do something that is in a menu, which is the way toolbar.prg
// is written (it sends WM_COMMAND messages, with the right params
// to produce EVENT_MENU events). You can easily change this, if
// you wish.
#ifdef RESOURCE
//TBD: put bitmaps in your resource file(s), and load them here
//TBD: set the bitmap id's/names, change the co-ordinates
//TBD: if using GetMenuId(), make sure you used that ID in your menu!
local aButtons := ;
{ {10, 4, 25, 22, LoadBitmap( , IDB_OPEN), GetMenuId(hMenu, "open")}, ;
{36, 4, 25, 22, LoadBitmap( , IDB_PRINT), GetMenuId(hMenu, "print")}, ;
{62, 4, 25, 22, LoadBitmap( , IDB_BROWSE), GetMenuId(hMenu, "browse")}, ;
{92, 4, 25, 22, LoadBitmap( , IDB_EXIT), GetMenuId(hMenu, "exit")}, ;
{122, 4, 25, 22, LoadBitmap( , IDB_ABOUT), GetMenuId(hMenu, "about")} }
#else
//TBD: read the appropriate bitmaps here
//TBD: set the bitmap names, change the co-ordinates
//TBD: if using GetMenuId(), make sure you used that ID in your menu!
local aButtons := ;
{ {10, 4, 25, 22, ReadDIB("open1.bmp"), GetMenuId(hMenu, "open")}, ;
{36, 4, 25, 22, ReadDIB("print1.bmp"), GetMenuId(hMenu, "print")}, ;
{62, 4, 25, 22, ReadDIB("browse1.bmp"), GetMenuId(hMenu, "browse")}, ;
{92, 4, 25, 22, ReadDIB("exit1.bmp"), GetMenuId(hMenu, "exit")}, ;
{122, 4, 25, 22, ReadDIB("help1.bmp"), GetMenuId(hMenu, "about")} }
#endif // RESOURCE
local aRect, hTBWnd
/*
* This sample puts the toolbar at the top of the window's
* client area. A child window is created to fill the area
* left. The user doesn't know (or care) the "childclient" exists,
* so just make it fill the area not used by the toolbar. Of
* course, this means changing its size if the main window changes
* size (msg WM_SIZE). The toolbar size needs to change as well
* (just the width in this example).
*
* This same technique can be useful at other times, e.g. the child
* might be a multi-line edit control.
*
* If you have a status bar, the easiest way to handle it is to
* make it another window (with no special border, no title bar,
* etc., and using WS_CHILD + WS_VISIBLE), put it at the bottom
* of the frame window, and reduce the child client's window height
* by the height of the status bar.
* (Yes, you do get extra windows. Don't worry.)
*/
aRect = GetClientRect(hWnd)
hTBWnd = ToolBar(hWnd, 0, 0, aRect[3], TB_HEIGHT, aButtons, ID_TOOLBAR)
return hTBWnd
#endif // WANT_TOOLBAR
static procedure Ctl3d(lOn)
static hLibCtl3d
local hInst := _GetInstance(), cDLL
if lOn .and. hLibCtl3d == nil
hLibCtl3d := LoadLibrary("ctl3d.dll")
if hLibCtl3d == nil .or. hLibCtl3d < 32
MessageBox( , "Unable to find CTL3D.DLL", "Error", MB_ICONSTOP)
hLibCtl3d := nil
else
cDLL := GetProcAddress(hLibCtl3d, "Ctl3dRegister", "Pascal", ;
"void", "int")
CallDLL(cDLL, hInst)
cDLL := GetProcAddress(hLibCtl3d, "Ctl3dAutoSubclass", "Pascal",;
"void", "int")
CallDLL(cDLL, hInst)
endif
elseif !lOn .and. hLibCtl3d != nil
cDLL := GetProcAddress(hLibCtl3d, "Ctl3dUnregister", "Pascal", ;
"void", "int")
CallDLL(cDLL, hInst)
FreeLibrary(hLibCtl3d)
hLibCtl3d := nil
endif
return