home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1990
/
11
/
threads2.c
< prev
next >
Wrap
Text File
|
1990-05-08
|
7KB
|
211 lines
ENVIRONMENTS
CHARLES PETZOLD
Vol. 9, No. 11
---------------------------------------------------------
THREADS2.C -- Demonstrates drawing from a second thread
(c) 1990, Ziff Communications Co.
PC Magazine * Charles Petzold, 1/90
---------------------------------------------------------
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
#include <mt\process.h>
#define STACKSIZE 4096 * sizeof (int)
typedef struct
{
HPS hps ;
BOOL fContinue ;
BOOL fTerminate ;
SHORT cxClient ;
SHORT cyClient ;
ULONG semTriggerDraw ;
ULONG semDoingDraw ;
}
THREADPARAMS ;
MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
VOID FAR SecondThread (THREADPARAMS *) ;
VOID DrawPattern (HPS, SHORT, SHORT, BOOL *) ;
VOID DrawLine (HPS, SHORT, SHORT, SHORT, SHORT) ;
HAB hab ;
int main (void)
{
static CHAR szClientClass [] = "Threads2" ;
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_SHELLPOSITION | FCF_TASKLIST ;
HMQ hmq ;
HWND hwndFrame, hwndClient ;
QMSG qmsg ;
hab = WinInitialize (0) ;
hmq = WinCreateMsgQueue (hab, 0) ;
WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, szClientClass, NULL,
0L, NULL, 0, &hwndClient) ;
while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
WinDispatchMsg (hab, &qmsg) ;
WinDestroyWindow (hwndFrame) ;
WinDestroyMsgQueue (hmq) ;
WinTerminate (hab) ;
return 0 ;
}
MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static int aiThreadStack [STACKSIZE / sizeof (int)] ;
static THREADPARAMS tp ;
HDC hdc ;
SIZEL sizl ;
switch (msg)
{
case WM_CREATE:
// create a presentation space for the window
hdc = WinOpenWindowDC (hwnd) ;
sizl.cx = 0 ;
sizl.cy = 0 ;
tp.hps = GpiCreatePS (hab, hdc, &sizl,
PU_PELS | GPIF_DEFAULT |
GPIT_MICRO | GPIA_ASSOC) ;
// start the thread after initialization
tp.fTerminate = FALSE ;
DosSemSet (&tp.semTriggerDraw) ;
DosSemClear (&tp.semDoingDraw) ;
if (_beginthread (SecondThread, aiThreadStack,
STACKSIZE, &tp) == -1)
{
WinMessageBox (HWND_DESKTOP, hwnd,
"Cannot create second thread!", "Threads2",
0, MB_OK | MB_ICONEXCLAMATION) ;
return 0 ;
}
return 0 ;
case WM_SIZE:
// stop the thread from drawing
tp.fContinue = FALSE ;
DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
tp.cxClient = SHORT1FROMMP (mp2) ;
tp.cyClient = SHORT2FROMMP (mp2) ;
return 0 ;
case WM_PAINT:
// stop the thread from drawing
tp.fContinue = FALSE ;
DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
// erase the whole window
WinInvalidateRect (hwnd, NULL, FALSE) ;
WinBeginPaint (hwnd, tp.hps, NULL) ;
GpiErase (tp.hps) ;
WinEndPaint (tp.hps) ;
// let the thread start again at the beginning
tp.fContinue = TRUE ;
DosSemSet (&tp.semDoingDraw) ;
DosSemClear (&tp.semTriggerDraw) ;
return 0 ;
case WM_DESTROY:
// stop the thread and clean up
tp.fTerminate = TRUE ;
tp.fContinue = FALSE ;
DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
GpiDestroyPS (tp.hps) ;
return 0 ;
}
return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
}
VOID _CDECL FAR SecondThread (THREADPARAMS * ptp)
{
HAB hab ;
hab = WinInitialize (0) ;
while (!ptp->fTerminate)
{
// wait for the semaphore to be cleared
DosSemWait (&ptp->semTriggerDraw, SEM_INDEFINITE_WAIT) ;
// draw the pattern until stopped
while (ptp->fContinue)
DrawPattern (ptp->hps, ptp->cxClient,
ptp->cyClient, &ptp->fContinue) ;
DosSemSet (&ptp->semTriggerDraw) ;
DosSemClear (&ptp->semDoingDraw) ;
}
WinTerminate (hab) ;
_endthread () ;
}
VOID DrawPattern (HPS hps, SHORT cxClient, SHORT cyClient, BOOL *pfContinue)
{
SHORT x, y ;
GpiSetMix (hps, FM_INVERT) ;
for (x = 0 ; *pfContinue && x < cxClient ; x++)
DrawLine (hps, 0, 0, x, cyClient) ;
for (y = cyClient ; *pfContinue && y > 0 ; y--)
DrawLine (hps, 0, 0, cxClient, y) ;
for (y = 0 ; *pfContinue && y < cyClient ; y++)
DrawLine (hps, cxClient, 0, 0, y) ;
for (x = 0 ; *pfContinue && x < cxClient ; x++)
DrawLine (hps, cxClient, 0, x, cyClient) ;
for (x = cxClient ; *pfContinue && x > 0 ; x--)
DrawLine (hps, cxClient, cyClient, x, 0) ;
for (y = 0 ; *pfContinue && y < cyClient ; y++)
DrawLine (hps, cxClient, cyClient, 0, y) ;
for (y = cyClient ; *pfContinue && y > 0 ; y--)
DrawLine (hps, 0, cyClient, cxClient, y) ;
for (x = cxClient ; *pfContinue && x > 0 ; x--)
DrawLine (hps, 0, cyClient, x, 0) ;
}
VOID DrawLine (HPS hps, SHORT x1, SHORT y1, SHORT x2, SHORT y2)
{
POINTL ptl ;
ptl.x = x1 ; ptl.y = y1 ; GpiMove (hps, &ptl) ;
ptl.x = x2 ; ptl.y = y2 ; GpiLine (hps, &ptl) ;
}