/* Function prototypes */
SHORT FUNCTYPE CreateThread(BYTE *stack, USHORT stackSize, HWND hwnd);
VOID FUNCTYPE Thread();
/* Global variables */
PBYTE stkbot;
SHORT rc;
TID threadID=0;
HWND notifyHwnd;
HAB hab;
HMQ hmq;
/* Individual Functions */
SHORT FUNCTYPE CreateThread(BYTE *stack, USHORT stackSize, HWND hwnd)
{
notifyHwnd = hwnd;
stkbot = &stack[ stackSize
- 1 ];
rc = DosCreateThread( (PFNTHREAD)Thread, &threadID, (VOID FAR *)stkbot );
return( rc );
}
VOID FUNCTYPE Thread()
{
QMSG qmsg;
hab = WinInitialize( NULL ); /* Initialize PM */
hmq = WinCreateMsgQueue( hab, 0 ); /* Create application msg queue */
WinPostMsg( notifyHwnd, VPMAPPC_THREAD_QUEUE, MPFROMLONG(hmq), 0L );
WinGetMsg( hab, &qmsg, (HWND)NULL, 0, 0 );
while( qmsg.msg != VPMAPPC_STOP_THREAD
);
{
.
.
.
... code to process each message
.
.
.
WinGetMsg( hab, &qmsg, (HWND)NULL, 0, 0);
}
WinDestroyMsgQueue( hmq
);
WinTerminate( hab );
}
!AppcDLL methods !
createThread: stackAddress stackSize: stackSize notifyHwnd: notifyHwnd
<api: 'CREATETHREAD' ulong ushort handle ushort>
^self invalidArgument!
!InvisibleNotifierWindow methods!
threadQueueEvent
"Description:
A message has been received.
Cause the associated event to occur.
Role: Private
Parameters: None
Returns: self"
^self event: #threadQueue!
verbDone
"Description:
A message has been received.
Cause the associated event to occur.
Role: Private
Parameters: None
Returns: self"
^self event: #verbDone!
vpmAppcThreadQueue: mp1 with: mp2
"Description:
A PM message has been received.
Remember the parameter values, add the message
to CurrentEvents, and return
to PM as soon as possible..
Role: Private
Parameters:
mp1 PMLong first parameter from sender
mp2 PMLong second parameter from sender
Requires:
Instance Variables: threadQueue
Returns: self"
threadQueue := mp1 deepCopy.
^self sendInputEvent: #threadQueueEvent!
vpmAppcVerbDone: mp1 with: mp2
"Description:
A PM message has been received.
Remember the parameter values, add the message
to CurrentEvents, and return
to PM as soon as possible..
Role: Private
Parameters:
mp1 PMLong first parameter from sender
mp2 PMLong second parameter from sender
Requires:
Instance Variables: vcbAddress
Returns: self"
vcbAddress:= mp1 deepCopy.
^self sendInputEvent: #verbDone! !
!AppcConversation methods !
initialize
appcLibrary := AppcDLL open.
notifierWindow := (AppcNotifierWindow new open;
when: #threadQueue perform: #threadQueue: ;
when: #verbDone perform: #verbDone: ;
yourself).
sem := Semaphore new.
threadStack := PMAddress copyToNonSmalltalkMemory:
(ByteArray new: 4096).
"Create the external thread"
appcLibrary
createThread: threadStack
asParameter
stackSize: 4096
notifyHwnd: notifierWindow
handle asParameter
"Wait for the #vpmAppcThreadQueue:with: message"
sem wait.
"Re-establish the main process as the receiver of
PM messages"
CurrentProcess makeUserIF.!
threadQueue: anAppcNotifierWindow
"Remember the thread's queue handle"
threadQueue := anAppcNotifierWindow threadQueue.
"Signal the main process that the message has been
received"
sem signal.
"Terminate the message receiver process"
Processor terminateActive.!