📄 threads.c
字号:
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools.
* Sample borrowed from Microsoft Visual C++ 1.00 for Microsoft Windows NT.
\******************************************************************************/
/*************************************************************************\
* PROGRAM: Threads.c
*
* PURPOSE:
*
* To demonstrate multi-threading.
*
* FUNCTIONS:
*
* WinMain() - Initializes a window, and process the message loop.
* MainWndProc() - Process messages, launches server & client threads.
* ThreadProc() - Draws a rectangle to a window.
* AsmThreadProc()- Assembly procedure that draws a rectangle to a window.
*
* COMMENTS:
*
* To Use:
* When starting this application, two threads are created. The
* first draws a green box, the second a red. Both boxes are moved
* about the screen as their individual threads calculate a new
* position and redraws the box.
*
* Note through out the sample "red thread" or "green thread" are
* referred to. This simply indicates the thread which draws either the
* red or green rectangle.
*
\*************************************************************************/
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include "threads.h"
/*************************************************************************\
*
* FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
*
* PURPOSE: calls initialization function, processes message loop
*
* COMMENTS:
*
\*************************************************************************/
int APIENTRY WinMain (HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASS wc;
UNREFERENCED_PARAMETER( lpCmdLine );
UNREFERENCED_PARAMETER( hPrevInstance );
hInst = hInstance;
wc.style = 0; // Replaces CS_SIZEREDRAW.
wc.lpfnWndProc = (WNDPROC)MainWndProc; // The client window procedure.
wc.cbClsExtra = 0; // No room reserved for extra data.
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_ASTERISK);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "ThreadsWClass";
RegisterClass(&wc);
hWind = CreateWindow ("ThreadsWClass",
"2 Threads Red = Asm, Green = C",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWind, nCmdShow);
while (GetMessage (&msg, NULL, 0, 0))
DispatchMessage (&msg); // Dispatch message to window.
return (msg.wParam); // Returns value from PostQuitMessage.
}
/*************************************************************************\
*
* FUNCTION: MainWndProc (hWind, UINT, UINT, LONG)
*
* PURPOSE: To process the windows messages. This procedure totally
* controls the priority of the threads.
*
* VARIABLES USED:
*
* - hThread1,hThread2
* Static handles to the two created threads.
*
* - ThreadID1, ThreadID2
* DWORDs used in the CreateThread call.
*
* - pColor1, pColor2
* DWORDs used to allocate some memory to use as a parameter
* to pass color values to the threads. This memory was
* allocated so that the threads wouldn't have to rely on this
* procedures stack for the values.
*
* - Buf[80]:
* Character buffer used to write messages to the user.
*
*
* MESSAGES:
*
* WM_DESTROY: - Terminates the threads and post the quit message.
* WM_CREATE: - Allocates memory to hold some color values, and
* creates the two threads.
* WM_COMMAND
*
*
*
* CALLED BY:
*
* WinMain();
*
* CALLS TO:
*
* ThreadProc();
* AsmThreadProc();
*
* COMMENTS:
*
*
\*************************************************************************/
LONG APIENTRY MainWndProc (HWND hWind,
UINT message,
UINT wParam,
LONG lParam)
{
static HANDLE hThread1, hThread2;
DWORD ThreadID1, ThreadID2;
CHAR Buf[80];
static DWORD *pColor1, *pColor2;
switch (message)
{
case WM_CREATE :
pColor1 = malloc(sizeof(DWORD));
*pColor1 = GREEN;
hThread1 = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)pColor1, 0,
(LPDWORD)&ThreadID1);
if (!hThread1)
{
wsprintf(Buf, "Error in creating C Green thread: %d",
GetLastError());
MessageBox (hWind, Buf, "WM_CREATE", MB_OK);
}
else
{
SetThreadPriority (hThread1, THREAD_PRIORITY_NORMAL);
}
Sleep (500); // Allow some time/distance between the
// thread boxes.
pColor2 = malloc(sizeof(DWORD));
*pColor2 = RED;
hThread2 = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE)AsmThreadProc,
(LPVOID)pColor2, 0,
(LPDWORD)&ThreadID2);
if (!hThread2)
{
wsprintf(Buf, "Error in creating Asm thread: %d",
GetLastError());
MessageBox (hWind, Buf, "WM_CREATE", MB_OK);
}
else
{
SetThreadPriority (hThread2, THREAD_PRIORITY_NORMAL);
}
return (0);
case WM_COMMAND:
switch (LOWORD(wParam))
{
return (0);
}
case WM_DESTROY : // When the window is destroyed
TerminateThread(hThread1, 0); // terminate the threads
TerminateThread(hThread2, 0);
free (pColor1); // Free allocated memory.
free (pColor2);
PostQuitMessage (0); // End it.
return (0);
}
return DefWindowProc (hWind, message, wParam, lParam);
}
/*************************************************************************\
*
* FUNCTION: ThreadProc (LPVOID)
*
* PURPOSE: A thread procedure which calculates position on the window
* and draws a colored rectangle. The color of the rectangle
* is determined by the input parameter.
*
* VARIABLES USED:
*
* - horizontal, vertical:
* Local int used to indicate the next directional move the
* rectangle will make.
*
* - ulx, uly:
* Local DWORD used for the Upper Left X corner and Upper
* Upper Left Y position of the rectangle.
*
* - rect: A RECT structure used to determin the current size of the
* window (in case the user resizes it).
*
* - hdc: HDC of the rectangle.
*
* - Time: A SYSTEMTIME structure. It's milli-second field is used
* to create an apparent random starting point for the
* rectangles.
*
* -hBrush: A handle to a Brush object, used to set the color of the
* rectangle.
*
* -width, height:
* Local DWORDs used for the width and height of the rectangles.
*
* CALLED BY:
*
* MainWndProc();
*
\*************************************************************************/
VOID ThreadProc ( LPVOID *Color)
{
int horizontal, vertical;
DWORD ulx, uly;
RECT rect;
HDC hDC;
SYSTEMTIME Time;
HANDLE hBrush;
DWORD width, height;
width = 20;
height = 20;
GetSystemTime (&Time); // Get the time.
do{}while(!GetClientRect(hWind, &rect)); // Loop, making sure window
// exists.
ulx = (Time.wMilliseconds % rect.right); // Use MOD to get a random
uly = (Time.wMilliseconds % rect.bottom); // position.
if(Time.wMilliseconds % 2 == 0) // Use MOD to pick random
{ // directions.
horizontal = 1;
vertical = 1;
}
else
{
horizontal = 1;
vertical = -1;
}
// Set color as per input
// parameter.
hBrush = CreateSolidBrush((COLORREF)*Color);
do
{ // do forever ...
GetClientRect( hWind, &rect);
if ( (ulx+width) > (DWORD)rect.right) // ... check for right edge,
{
ulx = rect.right - width;
horizontal = -1; // ... if so change direction;
}
if ((uly+height) > (DWORD)rect.bottom) // ... check for bottom edge,
{
uly = rect.bottom - height; // ... if so change dir.
vertical = -1;
}
if (uly <= 1) // ... check for right edge,
{
uly = 1;
vertical = 1;
}
if (ulx <= 1)
{ // ... check for top edge;
ulx = 1;
horizontal = 1;
}
hDC = GetDC(hWind); // ... Get DC,
SelectObject( hDC, hBrush); // ... Set brush color,
// ... Draw rectangle,
Rectangle (hDC, ulx, uly, ulx+width, uly+height);
ReleaseDC(hWind, hDC); // ... Release DC
ulx += horizontal; // ... Increment/decrement
uly += vertical; // ... position.
}while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -