The Design and Implementation of VIOWIN - Part 4

From EDM2
Jump to: navigation, search
The Design and Implementation of VIOWIN
Part: 1 2 3 4 5 6 7 8

The Fullscreen PM Subset

Written by Larry Salomon Jr.

Introduction

For my job, I once had to write an application that ran only when OS/2 booted from the floppy diskettes. Because I had no access to the functionality PM provides, I resorted to a line-oriented interface, where messages were displayed on the screen and scrolled up when necessary. It was a good interface, I thought; it was fully NLS enabled and had intelligent defaults so the user basically only had to type in the name of the application. Unfortunately, the Quality Assurance team didn't concur with my opinion. "We want a nice interface!" one exclaimed. "Yeah, one with different windows and such!" another shouted.

I was backed into a corner that I could only get out of one way.

This series describes the design and implementation of VIOWIN, a library that implements a subset of the Win APIs provided by PM for fullscreen sessions. The reasoning behind writing this series is that it provided me and will hopefully provide you with some unique insights into how a windowing system is developed; and since it is based on PM, your familiarity with the already defined interface will increase your capability to fully understand what is being described.

Obviously, this series assumes you have PM application development experience, but it isn't required.

Last Month

Last month, we finished looking at the remaining functions that are called from within the main() function, and realized that everything so far was quite trivial in nature. This month, we will delve into the window management functions including vwSendMsg() and vwPostMsg().

Window Management

Window management functions are, in my opinion, functions which act upon windows in some fashion. The list of functions within VIOWIN that fall into this category are listed below:

  • (MRESULT)vwDefWindowProc(hwndWnd,ulMsg,mpParm1,mpParm2);
  • (BOOL)vwEnableWindow(hwndWnd,bEnable);
  • (BOOL)vwInSendMsg(VOID);
  • (BOOL)vwIsWindow(hwndWnd);
  • (BOOL)vwIsWindowEnabled(hwndWnd);
  • (BOOL)vwPostMsg(hwndWnd,ulMsg,mpParm1,mpParm2);
  • (LONG)vwQueryBackColor(hwndWnd);
  • (HVWWND)vwQueryFocus(VOID);
  • (LONG)vwQueryForeColor(hwndWnd);
  • (HVWWND)vwQueryWindow(hwndWnd,lCmd);
  • (BOOL)vwQueryWindowPos(hwndWnd,pswpSwp);
  • (PVOID)vwQueryWindowPtr(hwndWnd,ulPtr);
  • (BOOL)vwQueryWindowRect(hwndWnd,prclRect);
  • (BOOL)vwQueryWindowText(hwndWnd,ulSzBuf,pchBuf);
  • (ULONG)vwQueryWindowTextLength(hwndWnd);
  • (LONG)vwQueryWindowULong(hwndWnd,lIndex);
  • (SHORT)vwQueryWindowUShort(hwndWnd,lIndex);
  • (MRESULT)vwSendMsg(hwndWnd,ulMsg,mpParm1,mpParm2);
  • (LONG)vwSetBackColor(hwndWnd,lColor);
  • (BOOL)vwSetFocus(hwndWnd);
  • (BOOL)vwSetForeColor(hwndWnd,lColor);
  • (BOOL)vwSetWindowPtr(hwndWnd,ulPtr,pvData);
  • (BOOL)vwSetWindowText(hwndWnd,pchText);
  • (BOOL)vwSetWindowULong(hwndWnd,lIndex,ulValue);
  • (BOOL)vwSetWindowUShort(hwndWnd,lIndex,usValue);
  • (BOOL)vwUpdateWindow(hwndWnd);
  • (HVWWND)vwWindowFromID(usId);

What a list! Fortunately, many of these functions are quite small in their implementation, so they will not occupy much space or take up too much time in their discussion.

Note!
It needs to be pointed out again that color support differs greatly from PM, due to the lack of a Gpi component.

Out Comes Our Spectacles

Let us take a closer look at each of the functions.

vwDefWindowPro
This is probably one of the more interesting functions, since its corresponding function in PM is not well-documented. Notice that only three messages are actually processed and the rest are simply ignored. Another important note is that this function actually handles the allocation of the window text in the WM_SETWINDOWPARAMS message.
vwEnableWindow
VIOWIN does nothing with the WS_DISABLED bit, though it probably should check this before allowing keystrokes to go to the window.
vwInSendMsg
One of the many trivial functions.
vwIsWindow
Another of the many trivial functions.
vwIsWindowEnabled
Another of the many trivial functions.
vwPostMsg
This function initializes the VWQMSG structure directly in the message queue, after first checking that there is space to store the message. In the first part of this series, you saw that the size of the queue was defined to be VW_SIZEQUEUE. This can be anything, and it is currently defined to be 50.
vwQueryBackColor
Another of the many trivial functions.
vwQueryFocus
Another of the many trivial functions.
vwQueryForeColor
Another of the many trivial functions.
#vwQueryWindow vwQueryWindow
Another of the many trivial functions, if you are familiar with the linked-list routines of Common/2.
vwQueryWindowText
This function is how I envisioned PM performing the same task.
vwQueryWindowPos
Another of the many trivial functions.
vwQueryWindowPtr
Another of the many trivial functions. Note the restriction on the index of the pointer to be retrieved.
vwQueryWindowRect
Another of the many trivial functions.
vwQueryWindowTextLength
This function is how I envisioned PM performing the same task.
vwQueryWindowULong
Note that only QWL_STYLE is accepted. I probably could have added QWL_HMQ and QWL_USER, but I was lazy.
#vwQueryWindowUShort vwQueryWindowUShort
Note that only QWS_ID is accepted. I probably could have added QWS_USER here also.
vwSendMsg
This is fairly trivial, once you see what it is doing, but I never really thought about this function until I had to implement it. PM's version of this function is significantly more complicated, since I has to address sending across processes, etc.
vwSetBackColor
Another of the many trivial functions.
vwSetFocus
Note that I do not send the WM_SETSELECTION nor the WM_ACTIVATE message.
vwSetForeColor
Another of the many trivial functions.
vwSetWindowPtr
Another of the many trivial functions.
vwSetWindowText
This function is how I envisioned PM performing the same task, with the exception that PM uses heaps for memory allocation and I use the memory management routines within Common/2.
vwSetWindowULong
Note that only QWL_STYLE is accepted.
vwSetWindowUShort
This is a stub in case I decide to accept QWS_USER in the future.
vwUpdateWindow
This is an interesting function. If the window is the desktop, we cannot simply send it a WM_PAINT message, since it will erase its children in the process. So, we send the desktop first and then the children each a WM_PAINT message.
vwWindowFromID
Another of the many trivial functions.

Summary

This month, much code was presented (see viowin4.zip) and the interesting details were discussed. I do realize that I have probably glossed over a lot of things; if there is something more you would like me to discuss, please send me email. I must add, though, that a lot of the "way it fits together" didn't actually occur to me until I needed to use the functions that I wrote, which resulted in modifications to the original attempts at the implementation of these functions.

Next month, we will look at the remaining sections of the base library: timers, cursors, drawing, rectangles, and anything else I have missed. The following parts will then begin to look at the implementation of the window classes: buttons, entryfields, and static controls.

vwDefWindowProc

MRESULT EXPENTRY vwDefWindowProc(HVWWND hwndWnd,
                                 ULONG ulMsg,
                                 MPARAM mpParm1,
                                 MPARAM mpParm2)
//-------------------------------------------------------------------------
// This is the default window procedure for windows.  It processes certain
// messages only.  Others, it passes to the desktop window, unless it is
// the desktop window which is calling this function.
//-------------------------------------------------------------------------
{
   HVWWND hwndDesktop;

   if (!vwIsWindow(hwndWnd)) {
      return MRFROMLONG(0);
   } /* endif */

   hwndDesktop=vwWindowFromID(VWWID_DESKTOP);

   switch (ulMsg) {
   case WM_QUERYWINDOWPARAMS:
      {
         PWNDPARAMS pwpParms;

         pwpParms=(PWNDPARAMS)PVOIDFROMMP(mpParm1);

         switch (pwpParms->fsStatus) {
         case WPM_CCHTEXT:
            pwpParms->cchText=strlen(hwndWnd->pchText)+1;
            return MRFROMLONG(TRUE);
         case WPM_TEXT:
            *pwpParms->pszText=0;


strncat(pwpParms->pszText,hwndWnd->pchText,pwpParms->cchText-1);

            return MRFROMLONG(TRUE);
         default:
            break;
         } /* endswitch */
      }
      break;
   case WM_SETWINDOWPARAMS:
      {
         PWNDPARAMS pwpParms;

         pwpParms=(PWNDPARAMS)PVOIDFROMMP(mpParm1);

         switch (pwpParms->fsStatus) {
         case WPM_TEXT:
            {
               PCHAR pchText;

               CmnMemAllocate(habAnchor->hcmWork,
                              pwpParms->cchText,
                              (PPVOID)&pchText);
               if (pchText==NULL) {
                  return FALSE;
               } /* endif */

               strcpy(pchText,pwpParms->pszText);

               if (hwndWnd->pchText!=NULL) {
                  CmnMemFree(habAnchor->hcmWork,hwndWnd->pchText);
               } /* endif */

               hwndWnd->pchText=pchText;
               return MRFROMLONG(TRUE);
            }
         default:
            break;
         } /* endswitch */
      }
      break;
   case WM_CLOSE:
      vwPostMsg(hwndWnd,WM_QUIT,0,0);
      return MRFROMLONG(0);
   default:
      break;
   } /* endswitch */

   if (hwndWnd!=hwndDesktop) {
      //-------------------------------------------------------------------
      // If the message wasn't processed and the window isn't the desktop,
      // pass the message up the chain.  Some messages get sent; the rest
      // get posted.
      //-------------------------------------------------------------------
      switch (ulMsg) {
      case WM_COMMAND:
      case WM_CONTROL:
      case WM_CHAR:
         if (vwInSendMsg()) {
            return vwSendMsg(hwndDesktop,ulMsg,mpParm1,mpParm2);
         } else {
            vwPostMsg(hwndDesktop,ulMsg,mpParm1,mpParm2);
            return MRFROMLONG(0);
         } /* endif */
      default:
         return MRFROMLONG(0);
      } /* endswitch */
   } else {
      return MRFROMLONG(0);
   } /* endif */
}

vwEnableWindow

BOOL EXPENTRY vwEnableWindow(HVWWND hwndWnd,BOOL bEnable)
//-------------------------------------------------------------------------
// This function sets or resets the WS_DISABLED bit for the window.
//
// Input:  hwndWnd - specifies the window handle
//         bEnable - flag indicating the desired enabled state
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   if (bEnable) {
      hwndWnd->ulStyle&=~WS_DISABLED;
   } else {
      hwndWnd->ulStyle|=WS_DISABLED;
   } /* endif */

   return TRUE;
}

vwInSendMsg

BOOL EXPENTRY vwInSendMsg(VOID)
//-------------------------------------------------------------------------
// This function determines if the system is in the middle of processing
// a vwSendMsg() call.
//
// Returns:  TRUE if in vwSendMsg(), FALSE otherwise
//-------------------------------------------------------------------------
{
   if (hmqQueue==NULL) {
      return FALSE;
   } /* endif */

   return habAnchor->bIsSendMsg;
}

vwIsWindow

BOOL EXPENTRY vwIsWindow(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function determines if the specified handle is a valid window
// handle or not.
//
// Input:  hwndWnd - handle to query
// Returns:  TRUE if the handle is valid, FALSE otherwise
//-------------------------------------------------------------------------
{
   ULONG ulNumItems;
   ULONG ulIndex;
   HVWWND hwndList;

   if (hmqQueue==NULL) {
      return FALSE;
   } /* endif */

   ulNumItems=CmnLstQueryRecordCount(habAnchor->hclWindows);

   for (ulIndex=0; ulIndex<ulNumItems; ulIndex++) {
      if (ulIndex==0) {
         hwndList=(HVWWND)CmnLstQueryRecord(habAnchor->hclWindows,0);
      } else {
         hwndList=(HVWWND)CmnLstQueryRelative(hwndList,LQR_NEXT);
      } /* endif */

      if (hwndList==hwndWnd) {
         return TRUE;
      } /* endif */
   } /* endfor */

   return FALSE;
}

vwIsWindowEnabled

BOOL EXPENTRY vwIsWindowEnabled(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function determines if the window is enabled or not.
//
// Input:  hwndWnd - handle to query
// Returns:  TRUE if the window is enabled, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   return ((hwndWnd->ulStyle & WS_DISABLED)==0);
}

vwPostMsg

BOOL EXPENTRY vwPostMsg(HVWWND hwndWnd,
                        ULONG ulMsg,
                        MPARAM mpParm1,
                        MPARAM mpParm2)
//-------------------------------------------------------------------------
// This function sends a message to the window.  This is done by
// building a VWQMSG structure and placing it in the queue.
//
// Input:  hwndWnd - specifies the window handle
//         ulMsg - specifies the message
//         mpParm1, mpParm2 - specify the message parameters
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   PVWQMSG pqmMsg;

   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   if (((hmqQueue->ulHead==0) && (hmqQueue->ulTail==VW_SIZEQUEUE)) ||
       (hmqQueue->ulHead==hmqQueue->ulTail+1)) {
      return FALSE;
   } /* endif */

   hmqQueue->ulTail++;
   if (hmqQueue->ulTail==VW_SIZEQUEUE) {
      hmqQueue->ulTail=0;
   } /* endif */

   pqmMsg=&hmqQueue->aqmMsgs[hmqQueue->ulTail];

   pqmMsg->hwndWnd=hwndWnd;
   pqmMsg->ulMsg=ulMsg;
   pqmMsg->mpParm1=mpParm1;
   pqmMsg->mpParm2=mpParm2;
   return TRUE;
}

vwQueryBackColor

LONG EXPENTRY vwQueryBackColor(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function returns the background color of the window.
//
// Input:  hwndWnd - specifies the window handle
// Returns:  VWCLR_* constant if successful, -1 otherwise
//-------------------------------------------------------------------------
{
   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return -1;
   } /* endif */

   return hwndWnd->lBackClr;
}

vwQueryFocus

HVWWND EXPENTRY vwQueryFocus(VOID)
//-------------------------------------------------------------------------
// This function returns the handle of the window currently with the
// focus.
//
// Returns:  window handle or NULLHANDLE if no window has the focus
//-------------------------------------------------------------------------
{
   //----------------------------------------------------------------------
   // Make sure we were initialized
   //----------------------------------------------------------------------
   if (hmqQueue==NULL) {
      return NULL;
   } /* endif */

   return habAnchor->hwndFocus;
}

vwQueryForeColor

LONG EXPENTRY vwQueryForeColor(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function returns the foreground color of the window.
//
// Input:  hwndWnd - specifies the window handle
// Returns:  VWCLR_* constant if successful, -1 otherwise
//-------------------------------------------------------------------------
{
   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return -1;
   } /* endif */

   return hwndWnd->lForeClr;
}

vwQueryWindow

HVWWND EXPENTRY vwQueryWindow(HVWWND hwndWnd,LONG lCmd)
//-------------------------------------------------------------------------
// This function returns the handle of a window relative to the specified
// window.
//
// Input:  hwndWnd - specifies the window handle
//         lCmd - specifies a QW_* constant
// Returns:  window handle if successful, NULLHANDLE otherwise
//-------------------------------------------------------------------------
{
   ULONG ulNumRecs;
   HVWWND hwndReturn;

   if (!vwIsWindow(hwndWnd)) {
      return NULL;
   } /* endif */

   ulNumRecs=CmnLstQueryRecordCount(habAnchor->hclWindows);

   switch (lCmd) {
   case QW_NEXT:
      hwndReturn=CmnLstQueryRelative(hwndWnd,LQR_NEXT);
      break;
   case QW_PREV:
      hwndReturn=CmnLstQueryRelative(hwndWnd,LQR_PREVIOUS);

      if (hwndReturn==vwWindowFromID(VWWID_DESKTOP)) {
         hwndReturn=NULL;
      } /* endif */
      break;
   case QW_TOP:
      hwndReturn=CmnLstQueryRecord(habAnchor->hclWindows,1);
      break;
   case QW_BOTTOM:
      hwndReturn=CmnLstQueryRecord(habAnchor->hclWindows,ulNumRecs-1);
      break;
   default:
      return NULL;
   } /* endswitch */

   return hwndReturn;
}

vwQueryWindowText

BOOL EXPENTRY vwQueryWindowText(HVWWND hwndWnd,ULONG ulSzBuf,PCHAR pchBuf)
//-------------------------------------------------------------------------
// This function returns the window text by sending the window a
// WM_QUERYWINDOWPARAMS message.
//
// Input:  hwndWnd - specifies the window handle
//         ulSzBuf - specifies the size of the buffer
//         pchBuf - points to the buffer to receive the text
// Output:  pchBuf - points to the buffer containing the text
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   WNDPARAMS wpParms;

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   if (pchBuf==NULL) {
      return FALSE;
   } /* endif */

   wpParms.fsStatus=WPM_TEXT;
   wpParms.cchText=ulSzBuf;
   wpParms.pszText=pchBuf;

   if (SHORT1FROMMP(vwSendMsg(hwndWnd,
                              WM_QUERYWINDOWPARAMS,
                              MPFROMP(&wpParms),
                              0))) {
      return TRUE;
   } else {
      return FALSE;
   } /* endif */
}

vwQueryWindowPos

BOOL EXPENTRY vwQueryWindowPos(HVWWND hwndWnd,PVWSWP pswpSwp)
//-------------------------------------------------------------------------
// This function returns the size and position of the window.
//
// Input:  hwndWnd - specifies the window handle
//         pswpSwp - points to the VWSWP structure to receive the result
// Output:  pswpSwp - points to the VWSWP structure containing the result
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   (*pswpSwp)=hwndWnd->swpSwp;
   return TRUE;
}

vwQueryWindowPtr

PVOID EXPENTRY vwQueryWindowPtr(HVWWND hwndWnd,ULONG ulPtr)
//-------------------------------------------------------------------------
// This function returns the specified window pointer.
//
// Input:  hwndWnd - specifies the window handle
//         ulPtr - specifies 0 or 1
// Returns:  specified window pointer if successful, NULL otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return NULL;
   } /* endif */

   if (ulPtr>1) {
      return NULL;
   } /* endif */

   return hwndWnd->pvData[ulPtr];
}

vwQueryWindowRect

BOOL EXPENTRY vwQueryWindowRect(HVWWND hwndWnd,PRECTL prclRect)
//-------------------------------------------------------------------------
// This function returns the size of the window.
//
// Input:  hwndWnd - specifies the window handle
//         prclRect - points to the RECTL structure to receive the result
// Output:  prclRect - points to the RECTL structure containing the result
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   prclRect->xLeft=0;
   prclRect->yBottom=0;
   prclRect->xRight=hwndWnd->swpSwp.ulCx;
   prclRect->yTop=hwndWnd->swpSwp.ulCy;
   return TRUE;
}

vwQueryWindowTextLength

ULONG EXPENTRY vwQueryWindowTextLength(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function returns the length of the window text.
//
// Input:  hwndWnd - specifies the window handle
// Returns:  length if successful, 0 otherwise
//-------------------------------------------------------------------------
{
   WNDPARAMS wpParms;

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   wpParms.fsStatus=WPM_CCHTEXT;

   if (SHORT1FROMMP(vwSendMsg(hwndWnd,
                              WM_QUERYWINDOWPARAMS,
                              MPFROMP(&wpParms),
                              0))) {
      return wpParms.cchText;
   } else {
      return 0;
   } /* endif */
}

vwQueryWindowULong

LONG EXPENTRY vwQueryWindowULong(HVWWND hwndWnd,LONG lIndex)
//-------------------------------------------------------------------------
// This function returns the value of the specified window variable.
//
// Input:  hwndWnd - specifies the window handle
//         lIndex - specifies a QWL_* constant
// Returns:  value of the variable if successful, -1 otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return -1;
   } /* endif */

   switch (lIndex) {
   case QWL_STYLE:
      return hwndWnd->ulStyle;
   default:
      return -1;
   } /* endswitch */
}

vwQueryWindowUShort

SHORT EXPENTRY vwQueryWindowUShort(HVWWND hwndWnd,LONG lIndex)
//-------------------------------------------------------------------------
// This function returns the value of the specified window variable.
//
// Input:  hwndWnd - specifies the window handle
//         lIndex - specifies a QWS_* constant
// Returns:  value of the variable if successful, -1 otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return -1;
   } /* endif */

   switch (lIndex) {
   case QWS_ID:
      return hwndWnd->usId;
   default:
      return -1;
   } /* endswitch */
}

vwSendMsg

MRESULT EXPENTRY vwSendMsg(HVWWND hwndWnd,
                           ULONG ulMsg,
                           MPARAM mpParm1,
                           MPARAM mpParm2)
//-------------------------------------------------------------------------
// This function sends a message to the window.  This is done by
// dereferencing the class and calling the window class procedure
// directly.
//
// Input:  hwndWnd - specifies the window handle
//         ulMsg - specifies the message
//         mpParm1, mpParm2 - specify the message parameters
// Returns:  value specific to the message sent
//-------------------------------------------------------------------------
{
   BOOL bOldSendMsg;
   MRESULT mrRc;

   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return MRFROMLONG(0);
   } /* endif */

   bOldSendMsg=habAnchor->bIsSendMsg;
   habAnchor->bIsSendMsg=TRUE;

   mrRc=(*(hwndWnd->pciClass->pfnWndProc))(hwndWnd,ulMsg,mpParm1,mpParm2);

   habAnchor->bIsSendMsg=bOldSendMsg;
   return mrRc;
}

vwSetBackColor

LONG EXPENTRY vwSetBackColor(HVWWND hwndWnd,LONG lColor)
//-------------------------------------------------------------------------
// This function sets the background color of the window.
//
// Input:  hwndWnd - specifies the window handle
//         lColor - specifies the new color
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   hwndWnd->lBackClr=lColor;
   return TRUE;
}

vwSetFocus

BOOL EXPENTRY vwSetFocus(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function sets the focus to another window.
//
// Input:  hwndWnd - specifies the handle of the window to receive the
//                   focus
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   HVWWND hwndLose;

   //----------------------------------------------------------------------
   // Validate the window handle
   //----------------------------------------------------------------------
   if ((hwndWnd!=NULL) && !vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   hwndLose=habAnchor->hwndFocus;

   //----------------------------------------------------------------------
   // Send a WM_SETFOCUS message to the window losing the focus.  Also,
   // send a WM_PAINT message (this deviates from PM).
   //----------------------------------------------------------------------
   if (hwndLose!=NULL) {
      habAnchor->hwndFocus=NULL;


vwSendMsg(hwndLose,WM_SETFOCUS,MPFROMHWND(hwndWnd),MPFROMLONG(FALSE));

      vwSendMsg(hwndLose,WM_PAINT,0,0);
   } /* endif */

   //----------------------------------------------------------------------
   // Send a WM_SETFOCUS message to the window gaining the focus.  Again,
   // also send a WM_PAINT message (deviation).
   //----------------------------------------------------------------------
   if (hwndWnd!=NULL) {
      vwSendMsg(hwndWnd,
                WM_SETFOCUS,
                MPFROMHWND(hwndLose),
                MPFROMLONG(TRUE));
      habAnchor->hwndFocus=hwndWnd;
      vwSendMsg(hwndWnd,WM_PAINT,0,0);
   } else {
      habAnchor->hwndFocus=NULL;
   } /* endif */

   return TRUE;
}

vwSetForeColor

BOOL EXPENTRY vwSetForeColor(HVWWND hwndWnd,LONG lColor)
//-------------------------------------------------------------------------
// This function sets the foreground color of the window.
//
// Input:  hwndWnd - specifies the window handle
//         lColor - specifies the new color
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   hwndWnd->lForeClr=lColor;
   return TRUE;
}

vwSetWindowPtr

BOOL EXPENTRY vwSetWindowPtr(HVWWND hwndWnd,ULONG ulPtr,PVOID pvData)
//-------------------------------------------------------------------------
// This function set the specified window pointer.
//
// Input:  hwndWnd - specifies the window handle
//         ulPtr - specifies 0 or 1
//         pvData - specifies the window pointer
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   if (ulPtr>1) {
      return FALSE;
   } /* endif */

   hwndWnd->pvData[ulPtr]=pvData;
   return TRUE;
}

vwSetWindowText

BOOL EXPENTRY vwSetWindowText(HVWWND hwndWnd,PCHAR pchText)
//-------------------------------------------------------------------------
// This function attempts to set the window text by sending the window
// a WM_SETWINDOWPARAMS message.  It is the responsibility of the window
// class to copy the text to its own workspace.
//
// Input:  hwndWnd - specifies the window handle
//         pchText - points to the new text
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   WNDPARAMS wpParms;

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   if (pchText!=NULL) {
      wpParms.pszText=pchText;
   } else {
      wpParms.pszText="";
   } /* endif */

   wpParms.fsStatus=WPM_TEXT;
   wpParms.cchText=strlen(pchText)+1;

   if (SHORT1FROMMP(vwSendMsg(hwndWnd,
                              WM_SETWINDOWPARAMS,
                              MPFROMP(&wpParms),
                              0))) {
      return TRUE;
   } else {
      return FALSE;
   } /* endif */
}

vwSetWindowULong

BOOL EXPENTRY vwSetWindowULong(HVWWND hwndWnd,LONG lIndex,ULONG ulValue)
//-------------------------------------------------------------------------
// This function sets the value of the specified window variable.
//
// Input:  hwndWnd - specifies the window handle
//         lIndex - specifies a QWL_* constant
//         ulValue - specifies the new value
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   switch (lIndex) {
   case QWL_STYLE:
      hwndWnd->ulStyle=ulValue;
      break;
   default:
      return FALSE;
   } /* endswitch */

   return TRUE;
}

vwSetWindowUShort

BOOL EXPENTRY vwSetWindowUShort(HVWWND hwndWnd,LONG lIndex,USHORT usValue)
//-------------------------------------------------------------------------
// This function sets the value of the specified window variable.
//
// Input:  hwndWnd - specifies the window handle
//         lIndex - specifies a QWS_* constant
//         usValue - specifies the new value
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   switch (lIndex) {
   default:
      return FALSE;
   } /* endswitch */

   return TRUE;
}

vwUpdateWindow

BOOL EXPENTRY vwUpdateWindow(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function updates the specified window.  If the window is the
// desktop, it updates all of the children also.
//
// Input:  hwndWnd - specifies the window handle
// Returns:  TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
   if (hwndWnd==VWHWND_DESKTOP) {
      hwndWnd=vwWindowFromID(VWWID_DESKTOP);
   } /* endif */

   if (!vwIsWindow(hwndWnd)) {
      return FALSE;
   } /* endif */

   if (vwQueryWindowUShort(hwndWnd,QWS_ID)==VWWID_DESKTOP) {
      //-------------------------------------------------------------------
      // Since the desktop is first in the list, traverse the list and
      // send each window a WM_PAINT message.
      //-------------------------------------------------------------------
      CmnLstTraverseList(habAnchor->hclWindows,(PFNRECFUNC)paintWindow);
   } else {
      paintWindow(hwndWnd);
   } /* endif */

   return TRUE;
}

vwWindowFromID

HVWWND EXPENTRY vwWindowFromID(USHORT usId)
//-------------------------------------------------------------------------
// This function returns the handle of the window with the specified id.
//
// Input:  usId - specifies the id to search for

// Returns:  handle of the window with the specified id if found,
NULLHANDLE

//           otherwise
//-------------------------------------------------------------------------
{
   HVWWND hwndFound;

   if (hmqQueue==NULL) {
      return NULL;
   } /* endif */

   //----------------------------------------------------------------------
   // If the id is -1, then the caller doesn't care about the window id,
   // so we should return NULL to allow for multiple windows with this
   // id can be used multiple times.
   //----------------------------------------------------------------------
   if (usId==(USHORT)-1) {
      return NULL;
   } /* endif */

   hwndFound=(HVWWND)CmnLstQueryRecord(habAnchor->hclWindows,0);
   hwndFound=(HVWWND)CmnLstSearchRecord(hwndFound,
                                        &usId,
                                        (PFNRECCOMP)_findWindowId);
   return hwndFound;
}
The Design and Implementation of VIOWIN
Part: 1 2 3 4 5 6 7 8