home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
srcos2
/
vapp.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-24
|
32KB
|
893 lines
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// VV VV //
// VV VV V - A Portable C++ GUI Framework VV VV //
// VV VV designed and written by VV VV //
// VV VV VV VV //
// VV VV Bruce E. Wampler, Ph.D. VV VV //
// VVV e-mail: bruce@objectcentral.com VVV //
// V V //
// Ported to OS/2 by Jon B. Hacker, Ph.D. //
// //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// //
// vapp.cxx - The vApp control object (For OS/2) //
// //
// Copyright (C) 1995-1998 Bruce E. Wampler //
// //
// This file is part of the V C++ GUI Framework. //
// //
// This library is free software; you can redistribute it and/or //
// modify it under the terms of the GNU Library General Public //
// License as published by the Free Software Foundation; either //
// version 2 of the License, or (at your option) any later version. //
// //
// This library is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
// Library General Public License for more details. //
// //
// You should have received a copy of the GNU Library General Public //
// License along with this library (see COPYING.LIB); if not, write to the //
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
// //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
#include <v/vos2.h> // for OS/2 stuff
#include <v/vapp.h> // my header file
#include <v/vwindow.h> // Win header
#include <v/vfont.h> // for font stuff
#include <v/vcmdwin.h>
#include <v/vTimer.h>
#include <v/vcmdpane.h>
#include <v/vthislst.h>
#include <stdlib.h>
// extern MRESULT EXPENTRY vTimerProc(HWND hwnd, UINT msg, UINT idTimer, ULONG mp2);
// Globals available to the world
vApp* theGlobalApp = NULL; // to be filled in upon instantiation
int (*pAppMain)(int, char**);
DebugMask DebugState;
static int _destroyed; // for destructor
// OS/2 bldlevel.exe signature
static char bldlevel[] = "@#Jon Hacker:1.21a100#@VGUI for OS/2";
static char copyright[] =
"****> Copyright (C) 1995-1999 Bruce E. Wampler; under terms of the\
GNU Library General Public License, version 2 <****";
//========================>>> vApp::vApp <<<=======================
vApp::vApp(VCONST char* appName, int simSDI, int frameHeight, int frameWidth) :
vBaseItem(appName) // constructor
{
// First, set the global pointer to the main App. This happens
// when the user declares the instance of the app, either from
// a vApp object direct, or an object from a class derived
// from the vApp class.
theGlobalApp = this; // this is our object
// now the data members
_curThis = 0;
_running = 0; // we are running
_WindowList = 0; // no windows registered
_CmdPaneList = 0; // no command panes registered
_clipText = 0;
_inExit = 0;
_simSDI = simSDI; // not used in OS/2
_frameWidth = frameWidth;
_frameHeight = frameHeight;
_DefaultHeight = 300; // default sizes for canvas window
_DefaultWidth = 500;
_destroyed = 0; // Not destroyed yet
_Frame = 0; // Not initiated yet.
// Set which debug items to show
DebugState.System = 0; // System debug messages
DebugState.CmdEvents = 0; // Show command events (buttons, etc.)
DebugState.MouseEvents = 0; // Show mouse events
DebugState.WindowEvents = 0; // Window events (resize, etc.)
DebugState.Build = 0; // Define/Build window
DebugState.BadVals= 0; // Error values
DebugState.Misc = 0; // Misc stuff
DebugState.Text = 0; // Text events
DebugState.Constructor = 0; // Show constructors
DebugState.Destructor = 0; // Show destructors
DebugState.User = 0; // Debug user events
DebugState.UserApp1 = 0; // Level 1 User App
DebugState.UserApp2 = 0; // Level 2 User App
DebugState.UserApp3 = 0; // Level 3 User App
DebugState.OS2Dev = 0; // OS/2 Development Debug
}
//========================>>> vApp::initialize <<<=======================
void vApp::initialize(int& argc, char** argv)
{
// Main interface to the parent windowing system
for (int argn = 1 ; argn < argc ; ++argn) // look for vDebug switch
{
if (strcmp(argv[argn],"-vDebug") == 0)
{
// Turn them all off
DebugState.System = 0; // System debug messages
DebugState.CmdEvents = 0; // Show command events (buttons, etc.)
DebugState.MouseEvents = 0; // Show mouse events
DebugState.WindowEvents = 0; // Window events (resize, etc.)
DebugState.Build = 0; // Define/Build window
DebugState.BadVals= 0; // Error values
DebugState.Misc = 0; // Misc stuff
DebugState.Text = 0; // Text events
DebugState.Constructor = 0; // Show constructors
DebugState.Destructor = 0; // Show destructors
DebugState.User = 0; // Debug user events
DebugState.UserApp1 = 0; // Level 1 User App
DebugState.UserApp2 = 0; // Level 2 User App
DebugState.UserApp3 = 0; // Level 3 User App
DebugState.OS2Dev = 0; // OS/2 Development Debug
for (char* cp = argv[argn+1] ; *cp ; ++cp)
{
switch (*cp)
{
case 'S':
DebugState.System = 1; // System debug messages
break;
case 'c':
DebugState.CmdEvents = 1; // Show command events (buttons, etc.)
break;
case 'm':
DebugState.MouseEvents = 1; // Show mouse events
break;
case 'w':
DebugState.WindowEvents = 1; // Window events (resize, etc.)
break;
case 'b':
DebugState.Build = 1; // Define/Build window
break;
case 'v':
DebugState.BadVals= 1; // Error values
break;
case 'o':
DebugState.Misc = 1; // (Other) Misc stuff
break;
case 't':
DebugState.Text = 1; // Text events
break;
case 'C':
DebugState.Constructor = 1; // Show constructors
break;
case 'D':
DebugState.Destructor = 1; // Show destructors
break;
case 'x':
DebugState.OS2Dev = 1; // OS/2 Development
break;
case 'U':
DebugState.User = 1; // Debug user events
break;
case '1':
DebugState.UserApp1 = 1; // Level 1 User App
break;
case '2':
DebugState.UserApp2 = 1; // Level 2 User App
break;
case '3':
DebugState.UserApp3 = 1; // Level 3 User App
break;
}
}
// Now fixup the argument list and break loop
int ia;
for (ia = argn ; ia < argc ; ++ia)
argv[ia] = argv[ia+2];
argv[ia] = 0;
argc -= 2; // eat the -vDebug args
break;
}
}
// This is pretty much the standard OS/2 startup code
// required by all OS/2 applications.
// We create an empty invisible frame to get
// things going, then defer to vWindow to generate
// useful visible windows.
// register the client window class
WinRegisterClass(_hab,
szvWindowClass, // window-class name
(PFNWP)&wpWindowProc, // window-procedure ID
CS_SIZEREDRAW, // default window style
4L); // reserved storage
// define frame window attributes
ULONG flCtlData= FCF_SYSMENU | // system menu
FCF_TITLEBAR | // titlebar
FCF_SIZEBORDER | // resizeable border
// FCF_MENU | // application menu
FCF_ICON | // associate icon
// FCF_TASKLIST | // app name in tasklist
// FCF_ACCELTABLE | // use an accelerator table
// FCF_MINMAX | // min/max buttons
FCF_SHELLPOSITION; // default window size & position
// create the empty frame window
_Frame = WinCreateStdWindow(HWND_DESKTOP, // parent is desktop
0, // frame window style
&flCtlData, // frame creation flags
// (PSZ)szWindowClass, // client-window class name
NULL, // suppress client window creation
_name, // title bar text
0, // client-window style
(HMODULE)NULL, // resource ID
vID_FRAME, // frame-window ID
0); // suppress client-window handle
_vHandle = _Frame;
SysDebug1(Build,"vApp::Initialize (dummy) _Frame = %u\n", _Frame)
/*
// center and size the window
// find the screen size for the system
LONG lDisplayWidth = ::WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
LONG lDisplayHeight = ::WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
// now set the origin and width to center the window on the screen
// if not using default values
if (_frameHeight <=0 || _frameWidth <=0 )
{
WinSetWindowPos(_Frame,
HWND_TOP,
(lDisplayWidth - _frameWidth)/2,
(lDisplayHeight - _frameHeight)/2,
_frameWidth,
_frameHeight,
SWP_SIZE | SWP_MOVE |
SWP_SHOW | SWP_ACTIVATE );
}
*/
// we get the system codepage it will be needed for menu templates
HPS hpsTemp = WinGetPS(_Frame);
_codePage = GpiQueryCp(hpsTemp);
WinReleasePS(hpsTemp);
hAccel = 0; // No accelerators
_workTimer = 0;
// WinUpdateWindow(_Frame);
_running = 1;
}
//======================>>> vApp::~vApp <<<=======================
vApp::~vApp()
{
// WARNING! This destructor never gets called automatically,
// at least with Borland C++ 4.5.
SysDebug(Destructor,"vApp::~vApp destructor\n")
if (_clipText != 0)
delete [] _clipText;
_destroyed = 1;
}
//======================>>> vApp::Exit <<<=======================
void vApp::Exit(void)
{
// Close All registered windows and exit
WindList *curWin;
vWindow *tmp;
SysDebug(Build,"vApp::Exit()\n")
/*
// this code was moved to doEventLoop()
if (_workTimer) // Stop events first
{
_workTimer->TimerStop();
delete _workTimer;
_workTimer = 0;
}
*/
_inExit = 1; // Kludge - CloseAppWin needs this
for (curWin = _WindowList ; curWin !=0 ; curWin = _WindowList)
{
int retv;
tmp = curWin->window;
if (IsHelpWin(tmp))
retv = CloseHelpWin(tmp);
else
{
retv = CloseAppWin(tmp); // use local or derived close app
}
if (!retv)
{
_inExit = 0;
return;
}
}
_inExit = 0; // done now, so can exit
AppExit(0);
}
//======================>>> vApp::AppExit <<<=======================
void vApp::AppExit(int exitVal)
{
if (!_inExit) // Only ONE, please!
{
WinPostQueueMsg(_hmq, WM_QUIT, (void*) exitVal ,0);
}
}
//========================>>> vApp::CheckEvents <<<=======================
// This should probably be handled with threads in OS/2.
void vApp::CheckEvents()
{
QMSG qmsg;
while (WinPeekMsg(_hab, &qmsg, 0, 0, 0, PM_REMOVE))
{
WinDispatchMsg(_hab,&qmsg);
}
}
//==================>>> vApp::CloseLastCmdWindow <<<=======================
void vApp::CloseLastCmdWindow(vWindow* win, int exitcode)
{
// This method, new in 1.21, allows an empty MDI frame for
// Windows. Default behavior is to exit on last close. To
// overide, the derived CloseLastCmdWindow should simply return.
AppExit(0);
}
//==================>>> vApp::ClipboardSetText <<<=======================
int vApp::ClipboardSetText(VCONST char* text) VCONST
{
// set the system clipboard to the value in text
int retval = 1;
int lines = 0; // how many lines in text
// count number of lines and leave extra space for /n
for (VCONST char *tp = text ; *tp ; ++tp)
if (*tp == '\n')
++lines; // count up lines
char* temp = new char[strlen(text)+lines+4]; // space for txt
char* to = temp;
char VCONST *from = text;
// this routine does a unix2dos sort of thing
// *to and *temp are the same thing
// *from and *text are the same thing
while (*from)
{
if (*from != '\r') // all except CRs
{
if (*from == '\n') // force all cr/lf or lf to cr/lf
*to++ = '\r';
*to++ = *from;
}
++from;
}
*to = 0; // terminate
int len = strlen(temp); // how long string really is
// Now, copy to system clipboard
PVOID hMem;
DosAllocSharedMem( &hMem, NULL, len+1, PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE );
if (hMem != 0)
{
strcpy((char*) hMem, temp); // copy our string
if (WinOpenClipbrd(_hab))
{
if (WinEmptyClipbrd(_hab))
{
WinSetClipbrdOwner (_hab, _Frame);
WinSetClipbrdData (_hab, (ULONG) hMem, CF_TEXT, CFI_POINTER);
}
WinCloseClipbrd(_hab);
}
else
{
// couldn't grab the clipboard so free up mem and punt
DosFreeMem (hMem);
retval = 0;
}
}
else
retval = 0;
delete [] temp;
return retval;
}
//====================>>> vApp::ClipboardGetText <<<=====================
char* vApp::ClipboardGetText() VCONST
{
// return a pointer to the clipboard text - we will allocate
// space for it as needed
if (!WinOpenClipbrd(_hab))
return 0;
if (_clipText != 0) // had some previous data
delete [] _clipText;
_clipText = 0; // make 0 for default return
PVOID hMem = (PVOID) WinQueryClipbrdData(_hab, CF_TEXT);
if (hMem != NULL) // Got some text data
{
char* str = (char*) hMem;
_clipText = new char[strlen(str)+1];
strcpy(_clipText, str);
}
WinCloseClipbrd (_hab);
return _clipText;
}
//====================>>> vApp::ClipboardCheckText <<<===================
int vApp::ClipboardCheckText() VCONST
{
ULONG format;
// check if text available on system clipboard
return WinQueryClipbrdFmtInfo (_hab, CF_TEXT, &format);
}
//====================>>> vApp::ClipboardClear <<<========================
void vApp::ClipboardClear() VCONST
{
// Clear out the clipboard
if (WinOpenClipbrd(_hab))
{
WinEmptyClipbrd(_hab);
WinCloseClipbrd(_hab);
}
}
//========================>>> vApp::CloseAppWin <<<=======================
int vApp::CloseAppWin(vWindow* win)
{
SysDebug(Build,"vApp::CloseAppWin()\n");
win->CloseWin(); // let the window close itself
unregisterWindow(win); // take it off the list
delete win; // free the window
return 1;
}
//========================>>> vApp::CloseHelpWin <<<=======================
int vApp::CloseHelpWin(vWindow* win)
{
SysDebug(Build,"vApp::CloseHelpWin()\n");
win->CloseWin(); // let the window close itself
unregisterWindow(win); // take it off the list
delete win; // free the window
return 1;
}
//========================>>> vApp::IsHelpWin <<<=======================
int vApp::IsHelpWin(vWindow *Win)
{
WindList *curWin;
for (curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
if (curWin->window == Win)
{
return (curWin->info == 0); // Help if 0
}
}
return 0;
}
//===========================>>> vApp::AppCommand <<<=========================
void vApp::AppCommand(vWindow* win, ItemVal id, ItemVal retval, CmdType ctype)
{
// Do nothing by default.
SysDebug1(CmdEvents,"vApp::AppCmd(id: %d)\n",id);
if (id == M_Exit)
Exit();
}
//========================>>> vApp::GetDefaultFont <<<=======================
vFont vApp::GetDefaultFont()
{
vFont sysF(vfDefaultSystem); // construct a system font instance
return sysF; // return it
}
//========================>>> vApp::getAppWinInfo <<<=======================
vAppWinInfo* vApp::getAppWinInfo(vWindow *Win)
{
// Search list to find associated vAppWinInfo.
WindList *curWin;
for (curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
if (curWin->window == Win)
{
return curWin->info; // return assocated info ptr
}
}
return 0;
}
//===========================>>> vApp::KeyIn <<<===========================
void vApp::KeyIn(vWindow* win, vKey key, unsigned int shift)
{
// Do nothing by default.
SysDebug(Misc,"vApp::KeyIn\n");
}
//========================>>> vApp::NewAppWin <<<=======================
vWindow* vApp::NewAppWin(vWindow* win, VCONST char* name, int w, int h,
vAppWinInfo* winInfo)
{
// The derived vApp needs to call this.
vWindow* thisWin = win;
vAppWinInfo* awinfo = winInfo;
SysDebug1(Build,"vApp::NewAppWin(%s)\n",name);
if (!thisWin) // Not created
thisWin = new vCmdWindow(name, w, h);
if (!winInfo)
awinfo = new vAppWinInfo(name);
registerWindow(thisWin, awinfo); // register this window
return thisWin;
}
//========================>>> vApp::NewHelpWin <<<=======================
vWindow* vApp::NewHelpWin(vWindow* win, VCONST char* name, int w, int h)
{
vWindow* thisWin = win;
SysDebug1(Build,"vApp::NewHelpWin(%s)\n",name);
if (!thisWin) // Not created
return 0;
registerWindow(thisWin, 0); // register this window
return thisWin;
}
//========================>>> vApp::registerWindow <<<=======================
void vApp::registerWindow(vWindow *Win, vAppWinInfo *awinfo)
{
WindList* newList = new WindList; // new cell to add to list
SysDebug1(Misc,"vApp::registerWindow - %s\n",Win->name())
newList->window = Win; // remember the window
newList->info = awinfo; // and its info class
newList->nextWinList = _WindowList; // link in at front
_WindowList = newList;
}
//========================>>> vApp::unregisterWindow <<<=======================
void vApp::unregisterWindow(vWindow *Win)
{
// Scan window list to unregister this window and free some space
WindList *curWin, *tmp, *last, *next;
last = 0;
for (curWin = _WindowList ; curWin !=0 ; curWin = next)
{
next = curWin->nextWinList;
if (curWin->window == Win)
{
SysDebug1(Misc,"vApp::unregisterWindow - %s\n",Win->name())
tmp = curWin;
if (curWin == _WindowList)
_WindowList = curWin->nextWinList;
else
last->nextWinList = curWin->nextWinList;
delete curWin->info; // free the info space
delete tmp; // free the list space
}
last = curWin;
}
}
//========================>>> vApp::registerCmdPane <<<======================
void vApp::registerCmdPane(vCommandPane* cmdPane)
{
CmdPaneList* newList = new CmdPaneList; // new cell to add to list
SysDebug(Misc,"vApp::registerCmdPane\n")
newList->commandPane = cmdPane; // remember the cmd pane
newList->nextCPList = _CmdPaneList; // link in at front
_CmdPaneList = newList;
}
//========================>>> vApp::unregisterCmdPane <<<=======================
void vApp::unregisterCmdPane(vCommandPane* cmdPane)
{
// Scan pane list to unregister this window and free some space
CmdPaneList *curCP, *tmp, *last, *next;
last = 0;
for (curCP = _CmdPaneList ; curCP !=0 ; curCP = next)
{
next = curCP->nextCPList;
if (curCP->commandPane == cmdPane)
{
SysDebug(Misc,"vApp::unregisterCmdPane\n")
tmp = curCP;
if (curCP == _CmdPaneList)
_CmdPaneList = curCP->nextCPList;
else
last->nextCPList = curCP->nextCPList;
delete tmp; // free the list space
}
last = curCP;
}
}
//========================>>> vApp::selectCmdPanes <<<=======================
/*
void vApp::selectCmdPanes(vWindow* parent)
{
// This is needed by the MDI interface conventions.
// This will turn off _isShown for panes that are children of other windows
// and turn on all cmd panes that are in our window
CmdPaneList *curCP;
// First, turn off all command panes in other windows
for (curCP = _CmdPaneList ; curCP !=0 ; curCP = curCP->nextCPList)
{
if ((curCP->commandPane)->_parentWin != parent)
{
(curCP->commandPane)->_isShown = 0;
if (WinIsWindow(_hab, (curCP->commandPane)->_wDialog) &&
WinIsWindowVisible((curCP->commandPane)->_wDialog))
{
WinShowWindow((curCP->commandPane)->_wDialog, FALSE);
}
}
}
// Now, turn ours on
for (curCP = _CmdPaneList ; curCP !=0 ; curCP = curCP->nextCPList)
{
if ((curCP->commandPane)->_parentWin == parent)
{
(curCP->commandPane)->_isShown = 1;
if (WinIsWindow(_hab, (curCP->commandPane)->_wDialog) &&
!WinIsWindowVisible((curCP->commandPane)->_wDialog))
{
WinShowWindow((curCP->commandPane)->_wDialog, TRUE);
}
}
}
}
*/
//========================>>> vApp::SendWindowCommandAll <<<=======================
void vApp::SendWindowCommandAll(ItemVal id, int val, CmdType ctype)
{
// send a command to all windows
for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
(curWin->window)->WindowCommand(id, val, ctype);
}
}
//========================>>> vApp::UpdateAllViews <<<=======================
void vApp::UpdateAllViews(vWindow* sender, int hint, void* pHint)
{
// Easy way to do MVC - call UpdateView in all windows
// This function is called by the user whenever a change is made to
// the model e.g the document. This causes vWindow::UpdateView to be
// called for every open window. The parameters are used to both filter and
// hint the windows on which actions to take in vWindow::UpdateView:
//
// sender: If this is not zero, this window will not invoke UpdateView,
// because typically the change of model was a result of
// an interaction with this window.
// hint: This should be an enum defined in your derived app class.
// Hints about which kind of change is made, so that only
// appropriate action is taken on appropriate windows.
// pHint: This is normally a pointer to the object representing the
// document
for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
if (curWin->window != sender)
(curWin->window)->UpdateView(sender, hint, pHint);
}
}
//========================>>> vApp::SetValueAll <<<=======================
void vApp::SetValueAll(ItemVal id, int val, ItemSetType setType)
{
// Set a Value in all windows
for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
(curWin->window)->SetValue(id, val, setType);
}
}
//======================>>> vApp::SetAppTitle <<<==========================
void vApp::SetAppTitle(VCONST char* title)
{
WinSetWindowText(_Frame, title);
}
//========================>>> vApp::SetStringAll <<<=======================
void vApp::SetStringAll(ItemVal id, VCONST char* str)
{
// Set a string in all windows
for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
(curWin->window)->SetString(id, str);
}
}
//========================>>> vApp::ShowList <<<=======================
int vApp::ShowList(void)
{
// This is a utility routine to show current information
//#ifdef HAS_PRINTF
printf("Registered windows:\n");
for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
{
printf(" %s\n",(curWin->window)->name());
}
//#endif
return 1;
}
//====================>>> _appWorkTimer::TimerTick <<<====================
void _appWorkTimer::TimerTick()
{
theApp->DispatchWork();
}
//========================>>> vApp::EnableWorkSlice <<<====================
int vApp::EnableWorkSlice(long slice)
{
if (slice > 0)
{
if (_workTimer == 0) // First time to start timer
{
_workTimer = new _appWorkTimer;
}
return _workTimer->TimerSet(slice);
}
else
{
if (_workTimer)
_workTimer->TimerStop();
}
return 1;
}
//========================>>> vApp::DispatchWork <<<=======================
void vApp::DispatchWork(void)
{
WorkSlice(); // Work Slice for App
// Call WorkSlice for all windows
for (WindList* curWin = _WindowList ; curWin !=0 ;
curWin = curWin->nextWinList)
{
(curWin->window)->WorkSlice();
}
}
//========================>>> vApp::doEventLoop <<<=======================
int vApp::doEventLoop(void)
{
// This is where we grab and handle events from the
// parent windowing system
QMSG qmsg;
while (WinGetMsg(_hab, &qmsg, 0, 0, 0))
{
// timer events come thru here. We look for those events not
// assigned to a particular window and send them to vTimerProc
// for handling.
if (qmsg.msg == WM_TIMER)
{
if (qmsg.hwnd == 0)
{
SHORT idTimer = SHORT1FROMMP(qmsg.mp1);
vTimerProc(qmsg.hwnd, qmsg.msg, idTimer, (ULONG) qmsg.mp2);
}
}
WinDispatchMsg (_hab, &qmsg);
}
// Turns out that the destructor for the static
// vApp object never gets called once PostQuitMessage is called. We do come
// through here, however, so here is where we can return these
// resources.
if (_workTimer)
{
_workTimer->TimerStop();
delete _workTimer;
}
WinDestroyWindow (_Frame);
return (int) qmsg.mp1;
}
//===========================>>> wpWindowProc <<<================================
MRESULT EXPENTRY wpWindowProc(HWND hwnd, ULONG message,
MPARAM mp1, MPARAM mp2)
{
static vWindow* createThis = 0;
vWindow* thisWin = (vWindow*) WinQueryWindowPtr(hwnd, 0);
if (!thisWin && message == WM_CREATE)
{
// We need to intercept the message here to recover the vWindow
// this of the window. It is sent in mp1
createThis = thisWin = (vWindow*)mp1; // remember the this!
}
else if (createThis != 0 && message == WM_ACTIVATE)
{
thisWin = createThis;
createThis = 0;
// WinSetActiveWindow (HWND_DESKTOP, hwnd);
}
if (!thisWin)
{
return WinDefWindowProc(hwnd, message, mp1, mp2);
}
else
{
return (MRESULT) thisWin->vWindowProc(hwnd, message, mp1, mp2);
}
}
//#########################################################################
// The user function AppMain is accessed through a pointer. This function
// stores the user's AppMain in a pointer to function that is used inside
// the V library. This was added to enable V Win32 DLL. It works also
// with a static library.
//
V_EXPORT void vRegisterAppMain( int (*p)(int, char**) )
{
pAppMain = p;
}
// Actually we should return vApp*, but VC++ complains that it
// can't find vGetApp when linking the application.
ULONG vGetApp()
{
return (ULONG) theGlobalApp;
}
//=========================>>> CMain <<<====================================
// this is just chained from main in vstartup.cpp
int CMain(int argc, char** argv)
{
int retcode;
// initialize app anchor block and message queue
theApp->_hab = WinInitialize( 0 );
if( theApp->_hab )
theApp->_hmq = WinCreateMsgQueue( theApp->_hab, 0 );
if( theApp->_hmq )
{
theApp->initialize(argc, argv); // Create top level widget
if ((retcode = pAppMain(argc, argv)) == 0) // call the app main program
theApp->doEventLoop(); // And enter the event loop
}
// cleanup and exit
if( theApp->_hmq )
WinDestroyMsgQueue( theApp->_hmq );
if( theApp->_hab )
WinTerminate( theApp->_hab );
return (retcode);
}
// Utilities
//=========================>>> vSysWarning <<<============================
void vSysWarning(VCONST char* msg)
{
WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
"V", 1, MB_ICONEXCLAMATION | MB_OK);
}
//=========================>>> vSys <<<============================
void vSysError(VCONST char* msg)
{
WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
"V", 1, MB_ICONEXCLAMATION | MB_OK);
theApp->AppExit(99);
}