The container application includes the following files:
The following sample illustrates the container application code:
================CONTAIN.C
================
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include "contain.h"
#include "phones.h"
/***********************************************************************/
/* Program Overview: */
/* */
/* This program creates a frame window as a parent, then creates */
/* a container window as a child. The frame window sizes the */
/* container to fill its client area. */
/* */
/* After the windows are created successfully, the container */
/* window is populated. First, the container is sent a message to */
/* allocate memory for each of the records which will be inserted. */
/* After the memory is allocated, we set the values for each record. */
/* (This sample program reads data from a static array - you could */
/* also load values from a file.) Then, the container is sent a */
/* message to insert the records (which makes them visible). */
/* */
/* This container is read-only, which means the end user cannot */
/* change the title text. It supports single selection. */
/* */
/* In the message loop, we must check for WM_CONTROL messages, */
/* which are generated from the container control. This sample */
/* processes CN_ENTER messages, when an item in the container is */
/* selected (either with the mouse or the keyboard), and */
/* CN_CONTEXTMENU messages, when a context menu is requested. The */
/* context menu allows the user to change the display mode of the */
/* container. Our container supports Icon, Text, and Name views. */
/* */
/* When a CN_ENTER message is received, we loop through the array */
/* of names until we find a match. On a match, we pop up a message */
/* box which contains the nickname, name, and number of the person */
/* selected. */
/* */
/***********************************************************************/
#pragma linkage (main,optlink)
INT main(VOID);
VOID LoadDatabase(HWND);
/***********************************************************************/
/* Main() - program entry point. */
/***********************************************************************/
MRESULT EXPENTRY LocalWndProc(HWND, ULONG, MPARAM, MPARAM);
HAB hab;
HWND hPopupMenu;
HWND hFrameWnd, hCnrWnd;
PFNWP SysWndProc;
INT main (VOID)
{
HMQ hmq;
FRAMECDATA fcd;
QMSG qmsg;
if (!(hab = WinInitialize(0)))
return FALSE;
if (!(hmq = WinCreateMsgQueue(hab, 0)))
return FALSE;
/***********************************************************************/
/* Set up the frame control data for the frame window. */
/***********************************************************************/
fcd.cb = sizeof(FRAMECDATA);
fcd.flCreateFlags = FCF_TITLEBAR |
FCF_SYSMENU |
FCF_SIZEBORDER |
FCF_SHELLPOSITION |
FCF_MINMAX |
FCF_TASKLIST;
fcd.hmodResources = NULLHANDLE;
fcd.idResources = 0;
/***********************************************************************/
/* Create the frame to hold the container control. */
/***********************************************************************/
hFrameWnd = WinCreateWindow(HWND_DESKTOP,
WC_FRAME,
"Phone Book",
0, 0, 0, 0, 0,
NULLHANDLE,
HWND_TOP,
0,
&fcd,
NULL);
/***********************************************************************/
/* Verify that the frame was created; otherwise, stop. */
/***********************************************************************/
if (!hFrameWnd)
return FALSE;
/***********************************************************************/
/* Set an icon for the frame window. */
/***********************************************************************/
WinSendMsg(hFrameWnd,
WM_SETICON,
(MPARAM)WinQuerySysPointer(HWND_DESKTOP,
SPTR_FOLDER,
FALSE),
NULL);
/***********************************************************************/
/* Create the container. */
/***********************************************************************/
hCnrWnd = WinCreateWindow(hFrameWnd,
WC_CONTAINER,
NULL,
CCS_AUTOPOSITION |
CCS_READONLY |
CCS_SINGLESEL,
0, 0, 0, 0,
hFrameWnd,
HWND_BOTTOM,
FID_CLIENT,
NULL,
NULL);
/***********************************************************************/
/* If we got it, fill it up. */
/***********************************************************************/
if (hCnrWnd)
LoadDatabase(hCnrWnd);
/***********************************************************************/
/* We must intercept the frame window's messages */
/* (to capture any input from the container control). */
/* We save the return value (the current WndProc), */
/* so we can pass it all the other */
/* messages the frame gets. */
/***********************************************************************/
SysWndProc = WinSubclassWindow(hFrameWnd, (PFNWP)LocalWndProc);
/***********************************************************************/
/* Load the popup menu from the resources */
/* and show the frame window. */
/***********************************************************************/
hPopupMenu = WinLoadMenu(HWND_OBJECT, NULLHANDLE, IDM_DISPLAY);
WinShowWindow(hFrameWnd, TRUE);
/***********************************************************************/
/* Standard PM message loop - get it, dispatch it. */
/***********************************************************************/
while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
{
WinDispatchMsg(hab, &qmsg);
}
/***********************************************************************/
/* Clean up on the way out. */
/***********************************************************************/
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
return TRUE;
}
/***********************************************************************/
/* LocalWndProc() - window procedure for the frame window. */
/* Called by PM whenever a message is sent to the frame. */
/***********************************************************************/
MRESULT EXPENTRY LocalWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
{
char szBuffer[80];
CNRINFO cnrInfo;
PNOTIFYRECORDENTER Selected;
POINTL pt;
int x;
switch(msg)
{
case WM_CONTROL:
switch (SHORT2FROMMP(mp1))
{
/***********************************************************************/
/* Context menu - usually right mouse button clicked */
/* on window. Popup a menu to allow the user to */
/* select a new view of the container. */
/***********************************************************************/
case CN_CONTEXTMENU:
WinQueryPointerPos(HWND_DESKTOP, &pt);
WinPopupMenu(HWND_DESKTOP,
hwnd,
hPopupMenu,
(SHORT)pt.x,
(SHORT)pt.y,
IDM_ICON,
PU_NONE |
PU_MOUSEBUTTON1 |
PU_KEYBOARD |
PU_SELECTITEM);
break;
case CN_ENTER:
/***********************************************************************/
/* User selected an item - we take the icon text */
/* and spin through the array of Friends, looking for */
/* a match - on match, print out the phone number */
/***********************************************************************/
Selected = (PNOTIFYRECORDENTER)mp2;
for (x = 0; x < MAXFRIENDS; x++)
{
if (!strcmpi(Friends[x].NickName,
Selected->pRecord->pszIcon))
{
sprintf(szBuffer,
"'%s' (%s) %s",
Friends[x].NickName,
Friends[x].FullName,
Friends[x].Phone);
WinMessageBox(HWND_DESKTOP,
HWND_DESKTOP,
szBuffer,
"Phone",
0,
MB_OK);
}
}
break;
}
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case IDM_ICON:
cnrInfo.flWindowAttr = CV_ICON;
break;
case IDM_NAME:
cnrInfo.flWindowAttr = CV_NAME;
break;
case IDM_TEXT:
cnrInfo.flWindowAttr = CV_TEXT;
break;
default:
return (*SysWndProc)(hwnd, msg, mp1, mp2);
break;
}
WinSendMsg(hCnrWnd,
CM_SETCNRINFO,
&cnrInfo,
MPFROMLONG(CMA_FLWINDOWATTR));
break;
/***********************************************************************/
/* Send the message to the usual WC_FRAME WndProc. */
/***********************************************************************/
default:
return (*SysWndProc)(hwnd, msg, mp1, mp2);
break;
}
return (*SysWndProc)(hwnd, msg, mp1, mp2);
}
/***********************************************************************/
/* LoadDatabase() - utility function */
/* called after the WC_CONTAINER window is created successfully, */
/* allocates and populates container records, and then inserts */
/* the records into the container window. */
/***********************************************************************/
VOID LoadDatabase (HWND hWnd)
{
HWND hIcon;
PRECORDCORE Address, FirstRec;
RECORDINSERT recsIn;
ULONG x;
/***********************************************************************/
/* The Icon view for each of the records in the */
/* container will use the standard File icon, */
/* so we grab the handle now for reference later. */
/***********************************************************************/
hIcon = WinQuerySysPointer(HWND_DESKTOP, SPTR_FILE, FALSE);
/***********************************************************************/
/* Allocate MAXFRIENDS records all at once - */
/* CM_ALLOCRECORD returns them in a linked list. */
/***********************************************************************/
Address = (PRECORDCORE)WinSendMsg(hWnd,
CM_ALLOCRECORD,
0,
MPFROMLONG(MAXFRIENDS));
/**********************************************************************/
/* We will need the first record's address to */
/* insert them into the container. */
/**********************************************************************/
FirstRec = Address;
/**********************************************************************/
/* Loop through the address book, loading as we go. */
/* Because the CM_ALLOCRECORD returns a linked list, */
/* the address of the next record is retrieved */
/* from each record as we go (preccNextRecord). */
/**********************************************************************/
for (x = 0; x < MAXFRIENDS; x++)
{
Address->cb = sizeof(RECORDCORE); /* Standard records */
Address->hptrIcon = hIcon; /* File icon */
Address->pszIcon = Friends[x].NickName;
Address->pszName = Friends[x].FullName;
Address->pszText = Friends[x].FullName;
Address = Address->preccNextRecord; /* Next record in list */
}
/**********************************************************************/
/* Set up the insert record structure to place */
/* the records in the container. */
/**********************************************************************/
recsIn.cb = sizeof(RECORDINSERT);
/* Put the records in after any others */
recsIn.pRecordOrder = (PRECORDCORE)CMA_END;
/* All the records are top level (not children of other records) */
recsIn.pRecordParent = NULL;
/* The icons are top level */
recsIn.zOrder = (USHORT)CMA_TOP;
/* Redraw the container */
recsIn.fInvalidateRecord = TRUE;
/* Set the number of records to insert */
recsIn.cRecordsInsert = MAXFRIENDS;
/**********************************************************************/
/* Insert the records into the container. */
/**********************************************************************/
WinSendMsg(hWnd,
CM_INSERTRECORD,
(PRECORDCORE)FirstRec,
&recsIn);
}
================
CONTAIN.RC
================
#include <os2.h>
#include "contain.h"
MENU IDM_DISPLAY
BEGIN
MENUITEM "Icon", IDM_ICON
MENUITEM "Text", IDM_TEXT
MENUITEM "Name", IDM_NAME
END
================
CONTAIN.H
================
#define DLG_ADDRBOOK 100
#define CNR_ADDRBOOK 101
#define PB_ADD 102
#define PB_DIAL 103
#define PHONEBOOK 256
#define IDM_DISPLAY 400
#define IDM_ICON 401
#define IDM_NAME 402
#define IDM_TEXT 403
================
CONTAIN.LNK
================
contain.obj
contain.exe
contain.map
contain.def
================
PHONES.H
================
#define MAXFRIENDS 9
/***********************************************************************/
/* This is a simple phone book database. */
/***********************************************************************/
typedef struct _Phones
{
PSZ NickName;
PSZ FullName;
PSZ Phone;
}PhoneBook;
/***********************************************************************/
/* Normal programs would read this data from a file. */
/***********************************************************************/
PhoneBook Friends[MAXFRIENDS] =
{
"Giles", "Kevin Giles", "214-555-1212",
"Bubba", "Hank Smith", "713-555-1212",
"Fred", "Fred Bicycle", "817-555-1212",
"Jack", "Jack Anjill", "919-555-1212",
"John", "John Richards", "214-555-1212",
"Toni", "Toni Henderson", "919-555-1212",
"Babe", "George Herman Ruth", "212-555-1212",
"Kevin", "Kevin Kortrel", "817-555-1212",
"Honest Abe", "Abraham Lincoln", "none"
};