.


:




:

































 

 

 

 


Blnherithandle bool: , TRUE. false

CrProces.h

#define IDM_EXIT 100

#define IDM_TEST 200

#define IDM_ABOUT 301

 

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);

CrProces.rc

#include "windows.h"

#include "CrProces.h"

 

MYAPP ICON DISCARDABLE "GENERIC.ICO"

MYAPP MENU DISCARDABLE

BEGIN

POPUP "&File"

BEGIN

MENUITEM "E&xit", IDM_EXIT

END

MENUITEM "&Test!", IDM_TEST

POPUP "&Help"

BEGIN

MENUITEM "&About My Application...", IDM_ABOUT

END

END

ABOUTBOX DIALOG 22, 17, 171, 43

STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU

CAPTION "My Application"

FONT 8, "MS Sans Serif"

{

CONTROL "MyApp", -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 3, 2, 16, 16

CONTROL "Generic Application", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 4, 100, 8

CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 116, 26, 50, 14

}

 

CrProces.c

#include <windows.h>

#include "CrProces.h"

 

HINSTANCE hInst; // current instance

LPCTSTR lpszAppName = "MyApp";

LPCTSTR lpszTitle = "My Application";

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

MSG msg;

HWND hWnd;

WNDCLASSEX wc;

 

// Register the main application window class.

//............................................

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc = (WNDPROC)WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(hInstance, lpszAppName);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wc.lpszMenuName = lpszAppName;

wc.lpszClassName = lpszAppName;

wc.cbSize = sizeof(WNDCLASSEX);

wc.hIconSm = LoadImage(hInstance, lpszAppName,

IMAGE_ICON, 16, 16,

LR_DEFAULTCOLOR);

 

if (!RegisterClassEx(&wc))

return(FALSE);

 

hInst = hInstance;

 

// Create the main application window.

//....................................

hWnd = CreateWindow(lpszAppName,

lpszTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0,

CW_USEDEFAULT, 0,

NULL,

NULL,

hInstance,

NULL

);

 

if (!hWnd)

return(FALSE);

 

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

 

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

 

return(msg.wParam);

}

 

HWND hList = NULL;

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

switch(uMsg)

{

case WM_CREATE:

// Create list box.

//.................

hList = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",

LBS_STANDARD | LBS_NOINTEGRALHEIGHT |

WS_CHILD | WS_VISIBLE,

0, 0, 10, 10,

hWnd, (HMENU)101,

hInst, NULL);

break;

 

case WM_SIZE:

if (wParam!= SIZE_MINIMIZED)

MoveWindow(hList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);

break;

 

case WM_COMMAND:

switch(LOWORD(wParam))

{

case IDM_TEST:

{

STARTUPINFO si;

PROCESS_INFORMATION pi;

 

// Initialize structures.

//.......................

ZeroMemory(&si, sizeof(STARTUPINFO));

ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

 

si.cb = sizeof(STARTUPINFO);

si.dwFlags = STARTF_USESHOWWINDOW;

si.wShowWindow = SW_SHOWNORMAL;

 

CreateProcess(NULL, "CALC", NULL, NULL, FALSE,

0, NULL, NULL, &si, &pi);

 

WaitForInputIdle(GetCurrentProcess(), INFINITE);

 

// Loop until process terminates.

//...............................

if (pi.hProcess)

{

DWORD dwExitCode = STILL_ACTIVE;

while (dwExitCode == STILL_ACTIVE)

{

WaitForSingleObject(pi.hProcess, 1000);

GetExitCodeProcess(pi.hProcess, &dwExitCode);

SendMessage(hList, LB_INSERTSTRING, 0, (LPARAM)"Waiting for Calc.");

UpdateWindow(hWnd);

}

SendMessage(hList, LB_INSERTSTRING, 0, (LPARAM)"Calc is Finished");

}

}

break;

 

case IDM_ABOUT:

DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)About);

break;

 

case IDM_EXIT:

DestroyWindow(hWnd);

break;

}

break;

 

case WM_DESTROY:

PostQuitMessage(0);

break;

 

default:

return(DefWindowProc(hWnd, uMsg, wParam, lParam));

}

 

return(0L);

}

 

LRESULT CALLBACK About(HWND hDlg,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

switch (message)

{

case WM_INITDIALOG:

return (TRUE);

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK

|| LOWORD(wParam) == IDCANCEL)

{

EndDialog(hDlg, TRUE);

return (TRUE);

}

break;

}

 

return (FALSE);

}

CreateThread . , , . , , , , , . , .

. , Windows NT/2000 . :

*

* . Windows NT/2000 Windows 9.x, , NULL.

* , . , 32- .

* 32- , .

* , , , .

* . .

CreateThread . , , , . CreateThread .

Windows 9.x Windows NT/2000 , . , . , , . Win32 API ( synchronization objects). , .

, . . . 1.

1.

: . , , . , .

(wait functions) API, , . . , , . , , .

(mutex object) " " (mutual exclusion). . , , , , . Winl6Lock Winl6Mutex Windows 9.x 16- GDI USER . , CreateMutex , .

(semaphore object) . ( ), . , . , .

. , . , . . , CreateSemaphore .

(event objects) . . : , , , .

(manual-reset event object) SetEvent. ResetEvent. PulseEvent . , , . , CreateEvent .

(auto-reset event object) . , . , . , OpenEvent .

, , . 2. , .

2.

,

, , . , Win32 API , . (critical section) , . InitializeCriticalSection.

EnterCriticalSection API. , , , , , , , LeaveCriticalSection.

,

Win32 API, , , . 3.

3. ,

Attach Threadlnput
CancelWartableTimer ,
CovertThreadToFiber
CreateEvent
CreateFiber
CreafeMutex
CreateProcess
CreateProcessAsUser ,
CreateRemoteThread ,
CreateSemaphore
CreateThread
Create WaitableTimer
DeleteCriticalSection
DeleteFiber
DuplicateHandle ,
EnterCriticalSection , ,
ExitProcess
ExitThread
GetCurrentFiber
GetCurrentProcess
GetCurrentProcessID
GetCurrentThread
GetCurrentThreadID
GetExitCodeProcess .
GetExitCodeThread .
GetFiberData ,
GelPriorityClass
GetProcessAffinityMask
GetProcessHeap
GetProcessHeaps , ,
GetProcessPriorityBoost
GetProcessShutdownParameters
GetProcessTimes
GetProcessVersion Windows
GetProcessWorkingSetSize
GetQueueStatus
GetThreadContext
GetThreadPriority
GetThreadPriorityBoost
GetThreadSelectorEntry (LDT)
GetThreadTimes
InitializeCrrticalSection
InterlockedCompareExchange
InterlockedDecrement
InterlockedExchange
InterlockedExchangeAdd
Interlockedlncrement
LeaveCriticalSection ,
MsgWaitForMultipleObjects , ,
MsgWaitForMultipieObjectsEx , MsgWaitForMuitipleObjects, , - ()
OpenEvent
OpenMutex
OpenProcess
OpenSemaphore
OpenWaitableTimer
PulseEvent , .
QueueUserAPC ()
RaiseException , . RaiseException
ReadProcessMemory
RegisterHotKey
ReleaseMutex
ReleaseSemaphore
ResetEvent
ResumeThread
SetEvent
SetPriorityClass
SetProcessAffinityMask
SetProcessPriorityBoost
SetProcessShufdownParameters
SetProcessWorkingSetSize
SetThreadAffinityMask
SetThreadContext
SetThreadldealProcessor
SetThreadPriority
SetThreadPriorityBoost
SetUnhandledExceptionFilter
SetWartableTimer
SignalObjectAndWait
Sleep .
SleepEx Sleep , - ()
SuspendThread
SwitchToFiber
TerminateProcess
TerminateThread
TIsAlloc
TIsFree
TIsGetValue ,
TIsGetValue ,
TryEnterCrrticalSection , ,
UnhandledExceptionFiter ,
UnregisteredHotKey
WattForlnputldle ,
WaitForMultipleObjects
WaitForMultipleObjectsEx , WaitForMultipleObjects, , - ()
WaitForSingleObject
WaitForSingleObjectEx , WaitForSingleObject, , - ()
WriteProcessMemory , ,

CreateEvent

CreateEvent , SetEvent. , . , . , WaitFor-SingleObject, . , .

HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpSecurityAttribs, BOOL bManualReset, BOOL nInitialState, LPCTSTR lpszEventName)

HANDLE: , . NULL. , GetLastError ERROR_ALREADY_EXIST, - 0.

winbase.h

. CreateProcess, DuplicateHandle, OpenEvent, ResetEvent, SetEvent, WaitForSingleObject, WaitForMultipleObjects.

, , . : Read, Write, Quit Help. , , . Read, Write. , , , . . , . .

CrEvent.h

#define IDM_EXIT 100

#define IDM_READ 200

#define IDM_WRITE 201

#define IDM_ABOUT 301

 

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);

 

CrEvent.rc

#include "windows.h"

#include "CrEvent.h"

 

MYAPP ICON DISCARDABLE "GENERIC.ICO"

MYAPP MENU DISCARDABLE

BEGIN

POPUP "&File"

BEGIN

MENUITEM "&Read", IDM_READ

MENUITEM "&Write", IDM_WRITE

MENUITEM SEPARATOR

MENUITEM "E&xit", IDM_EXIT

END

POPUP "&Help"

BEGIN

MENUITEM "&About My Application...", IDM_ABOUT

END

END

ABOUTBOX DIALOG 22, 17, 171, 43

STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU

CAPTION "My Application"

FONT 8, "MS Sans Serif"

{

CONTROL "MyApp", -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 3, 2, 16, 16

CONTROL "Generic Application", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 4, 100, 8

CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 116, 26, 50, 14

}

 

CrEvent.c

#include <windows.h>

#include "CrEvent.h"

 

HINSTANCE hInst; // current instance

 

LPCTSTR lpszAppName = "MyApp";

LPCTSTR lpszTitle = "My Application";

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

MSG msg;

HWND hWnd;

WNDCLASSEX wc;

 

// Register the main application window class.

//............................................

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc = (WNDPROC)WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(hInstance, lpszAppName);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wc.lpszMenuName = lpszAppName;

wc.lpszClassName = lpszAppName;

wc.cbSize = sizeof(WNDCLASSEX);

wc.hIconSm = LoadImage(hInstance, lpszAppName,

IMAGE_ICON, 16, 16,

LR_DEFAULTCOLOR);

 

if (!RegisterClassEx(&wc))

return(FALSE);

 

hInst = hInstance;

 

// Create the main application window.

//....................................

hWnd = CreateWindow(lpszAppName,

lpszTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0,

CW_USEDEFAULT, 0,

NULL,

NULL,

hInstance,

NULL

);

 

if (!hWnd)

return(FALSE);

 

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

 

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

 

return(msg.wParam);

}

 

#define SEMAPHORE_MAX_COUNT 10

 

LPCTSTR lpszReadSem = "Read Semaphore";

LPCTSTR lpszWriteEvent = "Write Event";

 

HANDLE hSemRead = NULL;

HANDLE hEventWrite = NULL;

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

switch(uMsg)

{

case WM_CREATE:

// Make the two synchronization objects.

//......................................

hSemRead = CreateSemaphore(NULL, 10, 10, lpszReadSem);

hEventWrite = CreateEvent(NULL, TRUE, TRUE, lpszWriteEvent);

break;

 

case WM_COMMAND:

switch(LOWORD(wParam))

{

case IDM_READ:

{

HANDLE hTmpSemRead;

HANDLE hTmpEventWrite;

 

hTmpSemRead= OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, lpszReadSem);

hTmpEventWrite = OpenEvent(SYNCHRONIZE, FALSE, lpszWriteEvent);

 

SetWindowText(hWnd, "Waiting for all Writes to Finish");

 

// Check that write manual reset event is signaled.

//.................................................

WaitForSingleObject(hEventWrite, INFINITE);

 

// Wait for semaphore.

//....................

WaitForSingleObject(hSemRead, INFINITE);

 

// Do the simulated read.

//.......................

SetWindowText(hWnd, "Reading");

Sleep(5000);

 

// Release semaphore.

//...................

ReleaseSemaphore(hSemRead, 1, NULL);

SetWindowText(hWnd, "Done Reading");

 

// Close the temporary handles.

//.............................

CloseHandle(hTmpSemRead);

CloseHandle(hTmpEventWrite);

}

break;

 

case IDM_WRITE:

{

DWORD dwSemaphoreCount = 0;

HANDLE hTmpSemRead;

HANDLE hTmpEventWrite;

 

 

hTmpSemRead = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, lpszReadSem);

hTmpEventWrite = OpenEvent(SYNCHRONIZE, FALSE, lpszWriteEvent);

 

// Wait for manual-reset event: it becomes nonsignaled.

//.....................................................

SetWindowText(hWnd, "Waiting for Write Event");

WaitForSingleObject(hEventWrite, INFINITE);

ResetEvent(hEventWrite);

SetWindowText(hWnd, "Waiting for All Reads to Finish");

 

// Release semaphore until its count is the maximum allowed.

//..........................................................

while (dwSemaphoreCount!= SEMAPHORE_MAX_COUNT)

{

WaitForSingleObject(hSemRead, INFINITE);

ReleaseSemaphore(hSemRead, 1, &dwSemaphoreCount);

dwSemaphoreCount++;

}

 

SetWindowText(hWnd, "Writing");

 

// Do the simulated write.

//........................

Sleep(10000);

SetWindowText(hWnd, "Done Writing");

 

// SetEvent: event object becomes signaled.

//.........................................

SetEvent(hEventWrite);

 

// Close the handles.

//...................

CloseHandle(hTmpSemRead);

CloseHandle(hTmpEventWrite);

}

break;

 

case IDM_ABOUT:

DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)About);

break;

 

case IDM_EXIT:

DestroyWindow(hWnd);

break;

}

break;

 

case WM_DESTROY:

if (hSemRead)

CloseHandle(hSemRead);

if (hEventWrite)

CloseHandle(hEventWrite);

 

PostQuitMessage(0);

break;

 

default:

return(DefWindowProc(hWnd, uMsg, wParam, lParam));

}

 

return(0L);

}

 

LRESULT CALLBACK About(HWND hDlg,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

switch (message)

{

case WM_INITDIALOG:

return (TRUE);

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK

|| LOWORD(wParam) == IDCANCEL)

{

EndDialog(hDlg, TRUE);

return (TRUE);

}

break;

}

 

return (FALSE);

}

 

SECURITY_ATTRIBUTES

typedef struct _SECURITY_ATTRIBUTES {

DWORD nLength;

LPVOID lpSecurityDescriptor;

BOOL blnheritHandle; } SECURITY_ATTRIBUTES;

nLength DWORD: .

lpSecurityDescriptor LPVOID: , . NULL, . Windows 9.x .

blnheritHandle BOOL: , TRUE. FALSE.

CreateMutex

CreateMutex , . , . , , , . , , , , . , ReleaseMutex , . MUTEX_ALL_ACCESS , . . , , CloseHandle. , .

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpSecurityAttribs, BOOL bInitialOwner, LPCTSTR lpszMutexName)

HANDLE: , . NULL. , GetLastError ERROR_ALREADY_EXIST; 0. GetLastError.

winbase.h

. CreateProcess, DuplicateHandle, OpenMutex, ReleaseMutex, WaitForSingleObject, WaitForMultipleObjects.

. Test!, , , , . Test! . .

. \local-sources\chap25\25-03.txt

CrMutex.h

#define IDM_EXIT 100

#define IDM_TEST 200

#define IDM_ABOUT 301

 

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);

 

CrMutex.rc

#include "windows.h"

#include "CrMutex.h"

 

MYAPP ICON DISCARDABLE "GENERIC.ICO"

 

MYAPP MENU DISCARDABLE

BEGIN

POPUP "&File"

BEGIN

MENUITEM "E&xit", IDM_EXIT

END

MENUITEM "&Test!", IDM_TEST

POPUP "&Help"

BEGIN

MENUITEM "&About My Application...", IDM_ABOUT

END

END

 

ABOUTBOX DIALOG 22, 17, 171, 43

STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU

CAPTION "My Application"

FONT 8, "MS Sans Serif"

{

CONTROL "MyApp", -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 3, 2, 16, 16

CONTROL "Generic Application", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 4, 100, 8

CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 116, 26, 50, 14

}

 

CrMutex.c

 

#include <windows.h>

#include "CrMutex.h"

 

HINSTANCE hInst; // current instance

 

LPCTSTR lpszAppName = "MyApp";

LPCTSTR lpszTitle = "My Application";

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

MSG msg;

HWND hWnd;

WNDCLASSEX wc;

 

// Register the main application window class.

//............................................

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc = (WNDPROC)WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(hInstance, lpszAppName);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wc.lpszMenuName = lpszAppName;

wc.lpszClassName = lpszAppName;

wc.cbSize = sizeof(WNDCLASSEX);

wc.hIconSm = LoadImage(hInstance, lpszAppName,

IMAGE_ICON, 16, 16,

LR_DEFAULTCOLOR);

 

if (!RegisterClassEx(&wc))

return(FALSE);

 

hInst = hInstance;

 

// Create the main application window.

//....................................

hWnd = CreateWindow(lpszAppName,

lpszTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0,

CW_USEDEFAULT, 0,

NULL,

NULL,

hInstance,

NULL

);

 

if (!hWnd)

 

return(FALSE);

 

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

 

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

 

return(msg.wParam);

}

 

 

LPCTSTR lpszMutex = "Example Mutex";

 

HANDLE hMutex = NULL;

 

// Child thread procedure waits until mutex becomes signaled,

// holds the object for five seconds, and then releases it.

//...........................................................

DWORD WINAPI ChildThreadProc(LPDWORD lpData)

{

TCHAR szBuffer[128];

HWND hWnd = (HWND)lpData;

HANDLE hTmpMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, lpszMutex);

 

wsprintf(szBuffer,"Thread %x waiting for Mutex %x",

GetCurrentThreadId(), hMutex);

 

SendMessage(hWnd, WM_USER, 0, (LPARAM)szBuffer);

 

// Wait for signaled mutex.

//.........................

WaitForSingleObject(hMutex, INFINITE);

wsprintf(szBuffer,"Thread %x got mutex!", GetCurrentThreadId());

SendMessage(hWnd, WM_USER, 0, (LPARAM)szBuffer);

 

// Shut out other threads.

//........................

Sleep(5000);

 

// Release mutex.

//...............

wsprintf(szBuffer,"Thread %x is done with mutex", GetCurrentThreadId());

SendMessage(hWnd, WM_USER, 0, (LPARAM) szBuffer);

ReleaseMutex(hMutex);

 

CloseHandle(hMutex);

return(0);

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

static HWND hList = NULL;

static int nMsgNum = 0;

 

switch(uMsg)

{

case WM_CREATE:

// Create list box.

//.................

hList = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",

LBS_STANDARD | LBS_NOINTEGRALHEIGHT |

WS_CHILD | WS_VISIBLE,

0, 0, 10, 10,

hWnd, (HMENU)101,

hInst, NULL);

 

hMutex = CreateMutex(NULL, FALSE, lpszMutex);

break;

 

case WM_SIZE:

if (wParam!= SIZE_MINIMIZED)

MoveWindow(hList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);

break;

 

case WM_USER:

{

TCHAR szBuffer[128];

 

wsprintf(szBuffer, "%3d: %s", ++nMsgNum, (LPTSTR)lParam);

SendMessage(hList, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szBuffer);

}

break;

 

case WM_COMMAND:

switch(LOWORD(wParam))

{

case IDM_TEST:

{

DWORD id;

 

// Make a thread.

//...............

CreateThread(NULL, 0, ChildThreadProc, hWnd, 0, &id);

}

break;

 

case IDM_ABOUT:

DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)About);

break;

 

case IDM_EXIT:

DestroyWindow(hWnd);

break;

}

break;

 

case WM_DESTROY:

if (hMutex)

CloseHandle(hMutex);

 

PostQuitMessage(0);

break;

 

default:

return(DefWindowProc(hWnd, uMsg, wParam, lParam));

}

 

return(0L);

}

 

LRESULT CALLBACK About(HWND hDlg,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

switch (message)

{

case WM_INITDIALOG:

return (TRUE);

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK

|| LOWORD(wParam) == IDCANCEL)

{

EndDialog(hDlg, TRUE);

return (TRUE);

}

break;

}

 

return (FALSE);

}

CreateSemaphore

CreateSemaphore . , , , , . (, WaitForSingleObject), . Release-Semaphore, . , ISemMax-Count.

DWORD CreateSemaphore(LPSECURITY_ATTRIBUTES lpThreadSecurity, LONG lSemInitialCount, LONG lSemMaxCount, LPCTSTR lpszSemName)

winbase.h

. CloseHandle, DuplicateHandle, OpenSemaphore, ReleaseSemaphore, WaitForSingleObject, WaitForMultipleObjects.

. Test!, . , , , . , Test!, .

CrSem.h

#define IDM_EXIT 100

#define IDM_TEST 200

#define IDM_ABOUT 301

 

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);

 

CrSem.rc

#include "windows.h"

#include "CrSem.h"

 

MYAPP ICON DISCARDABLE "GENERIC.ICO"

 

MYAPP MENU DISCARDABLE

BEGIN

POPUP "&File"

BEGIN

MENUITEM "E&xit", IDM_EXIT

END

MENUITEM "&Test!", IDM_TEST

POPUP "&Help"

BEGIN

MENUITEM "&About My Application...", IDM_ABOUT

END

END

 

ABOUTBOX DIALOG 22, 17, 171, 43

STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU

CAPTION "My Application"

FONT 8, "MS Sans Serif"

{

CONTROL "MyApp", -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 3, 2, 16, 16

CONTROL "Generic Application", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 4, 100, 8

CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 116, 26, 50, 14

}

 

CrSem.c

#include <windows.h>

#include "CrSem.h"

 

HINSTANCE hInst; // current instance

 

LPCTSTR lpszAppName = "MyApp";

LPCTSTR lpszTitle = "My Application";

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

MSG msg;

HWND hWnd;

WNDCLASSEX wc;

 

// Register the main application window class.

//............................................

wc.style = CS_HREDRAW | CS_VREDRAW;

 

wc.lpfnWndProc = (WNDPROC)WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(hInstance, lpszAppName);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wc.lpszMenuName = lpszAppName;

wc.lpszClassName = lpszAppName;

wc.cbSize = sizeof(WNDCLASSEX);

wc.hIconSm = LoadImage(hInstance, lpszAppName,

IMAGE_ICON, 16, 16,

LR_DEFAULTCOLOR);

 

if (!RegisterClassEx(&wc))

return(FALSE);

 

hInst = hInstance;

 

// Create the main application window.

//....................................

hWnd = CreateWindow(lpszAppName,

lpszTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0,

CW_USEDEFAULT, 0,

NULL,

NULL,

hInstance,

NULL

);

 

if (!hWnd)

return(FALSE);

 

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

 

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

 

return(msg.wParam);

}

 

 

LPCTSTR lpszSemaphore = "Test Semaphore";

 

// This is a child thread procedure that waits for a semaphore,

// holds the semaphore for five seconds, and releases the semaphore.

// Threads that cannot get semaphores will wait until other threads exit.

//.......................................................................

 

DWORD WINAPI ChildThreadProc(LPDWORD lpData)

{

TCHAR szBuffer[256];

DWORD dwSemCount = 0;

HWND hList = (HWND)lpData;

HANDLE hSemaphore = OpenSemaphore(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, lpszSemaphore);

 

wsprintf(szBuffer,"Thread %x waiting for semaphore %x",

GetCurrentThreadId(), hSemaphore);

 

SendMessage(hList, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szBuffer);

 

// Check for signaled semaphore.

//..............................

WaitForSingleObject(hSemaphore, INFINITE);

wsprintf(szBuffer,"Thread %x got semaphore", GetCurrentThreadId());

SendMessage(hList, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szBuffer);

Sleep(5000);

 

// Release semaphore.

//...................

ReleaseSemaphore(hSemaphore, 1, &dwSemCount);

 

wsprintf(szBuffer,"Thread %x is done with semaphore. Its count was %ld.",

GetCurrentThreadId(), dwSemCount);

 

SendMessage(hList, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szBuffer);

 

CloseHandle(hSemaphore);

 

return(0);

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

static HWND hList = NULL;

static HANDLE hSemaphore = NULL;

 

switch(uMsg)

{

case WM_CREATE:

// Create list box.

//.................

hList = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",

LBS_STANDARD | LBS_NOINTEGRALHEIGHT |

WS_CHILD | WS_VISIBLE,

0, 0, 10, 10,

hWnd, (HMENU)101,

hInst, NULL);

 

hSemaphore = CreateSemaphore(NULL, 4, 4, lpszSemaphore);

break;

 

case WM_SIZE:

if (wParam!= SIZE_MINIMIZED)

MoveWindow(hList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);

break;

 

case WM_COMMAND:

switch(LOWORD(wParam))

{

case IDM_TEST:

{

DWORD dwChildId;

 

CreateThread(NULL, 0, ChildThreadProc, hList, 0, &dwChildId);

}

break;

 

case IDM_ABOUT:

DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)About);

break;

 

case IDM_EXIT:

DestroyWindow(hWnd);

break;

}

break;

 

case WM_DESTROY:

if (hSemaphore)

CloseHandle(hSemaphore);

 

PostQuitMessage(0);

break;

 

default:

return(DefWindowProc(hWnd, uMsg, wParam, lParam));

}

 

return(0L);

}

 

LRESULT CALLBACK About(HWND hDlg,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

switch (message)

{

case WM_INITDIALOG:

return (TRUE);

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK

|| LOWORD(wParam) == IDCANCEL)

{

EndDialog(hDlg, TRUE);

return (TRUE);

}

break;

}

return (FALSE);

}

CreateThread

CreateThread , . . . , lpStartAddr. , DWORD, ExitThread. , , GetExitCodeThread.

THREAD_PRIORITY_NORMAL. GetThreadPriority SetThreadPriority. , CloseHandle.

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadSecurity, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD dwCreateFlags, LPDWORD lpdwThreadId)

HANDLE: , . NULL. GetLastError.

winbase.h

. CloseHandle, CreateProcess,CreateRemoteThread, ExitThread, GetExitCodeThread, GetLastError, OpenThreadToken, SetErrorMode, TerminateProcess, TerminateThread.

. CreateSemaphore.

EnterCriticalSection

EnterCriticalSection . , . . , EnterCriticalSection , . LeaveCriticalSection , , . , EnterCriticalSection TryEnterCriticalSection , .

VOID EnterCriticalSection (LPCRITICAL_SECTION lpcs)

lpcs LPCRITICAL_SECTION: .

winbase.h

. CreateMutex, DeleteCriticalSection, InitializeCriticalSection, LeaveCriticalSection.

( ) . , Test!, . .

. \local-sources\chap25\25-07.txt

EntCrSec.h

#define IDM_EXIT 100

#define IDM_TEST 200

#define IDM_ABOUT 301

 

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);

 

EntCrSec.rc

#include "windows.h"

#include "EntCrSec.h"

 

MYAPP ICON DISCARDABLE "GENERIC.ICO"

 

MYAPP MENU DISCARDABLE

BEGIN

POPUP "&File"

BEGIN

MENUITEM "E&xit", IDM_EXIT

END

MENUITEM "&Test!", IDM_TEST

POPUP "&Help"

BEGIN

MENUITEM "&About My Application...", IDM_ABOUT

END

END

 

ABOUTBOX DIALOG 22, 17, 171, 43

STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU

CAPTION "My Appl



<== | ==>
. |
:


: 2016-10-22; !; : 882 |


:

:

, , .
==> ...

1345 - | 1264 -


© 2015-2024 lektsii.org - -

: 0.942 .