Windows NT

       

MutexSDI


Mutex MultiSDI, . MutexSDI Mutex. , MutexSDI , , Mutex ( , -, ).

4.3. MultiSDI, .

4.3. mutexsdi/mutexsdi.c

#define STRICT

#include <windows.h>

#include <windowsx.h>

#include <process.h>

#include <stdio.h>

#include "resource.h"

#include "afxres.h"

#include "mutexsdi.h"

HINSTANCE hInst;

char szAppName[] = "MutexMultiSDI";



char szAppTitle[] = "Multithread SDI Application with Mutex";

// Mutex

char szMutexName[] = "$MyMutex$MutexMultiSDI$";

// Mutex

HANDLE hMutex;

//

BOOL fTerminate = FALSE;

//

HANDLE hThreads[3];

// -----------------------------------------------------

// WinMain

// -----------------------------------------------------

int APIENTRY

WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

{

WNDCLASSEX wc;

HWND hWnd;

MSG msg;

//

hInst = hInstance;

// Mutex

hMutex = CreateMutex(NULL, FALSE, szMutexName);

if(hMutex == NULL)

{

MessageBox(NULL, "CreateMutexError",

szAppTitle, MB_OK | MB_ICONEXCLAMATION);

return 0l;

}

// ,

if(GetLastError() == ERROR_ALREADY_EXISTS)


{

MessageBox(NULL, "MutexSDI already started",

szAppTitle, MB_OK | MB_ICONEXCLAMATION);

return 0l;

}

//

memset(&wc, 0, sizeof(wc));

wc.cbSize = sizeof(WNDCLASSEX);

wc.hIconSm = LoadImage(hInst,

MAKEINTRESOURCE(IDI_APPICONSM),

IMAGE_ICON, 16, 16, 0);

wc.style = 0;

wc.lpfnWndProc = (WNDPROC)WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInst;

wc.hIcon = LoadImage(hInst,

MAKEINTRESOURCE(IDI_APPICON),

IMAGE_ICON, 32, 32, 0);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

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

wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);

wc.lpszClassName = szAppName;

if(!RegisterClassEx(&wc))

if(!RegisterClass((LPWNDCLASS)&wc.style))

return FALSE;



//

hWnd = CreateWindow(szAppName, szAppTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

NULL, NULL, hInst, NULL);

if(!hWnd) return(FALSE);

//

//

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

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

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

// -----------------------------------------------------

// WndProc

// -----------------------------------------------------

LRESULT WINAPI

WndProc( HWND hWnd, UINT msg, WPARAM wParam,

LPARAM lParam)

{

switch(msg)

{

HANDLE_MSG(hWnd, WM_CREATE, WndProc_OnCreate);

HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);

HANDLE_MSG(hWnd, WM_PAINT, WndProc_OnPaint);

HANDLE_MSG(hWnd, WM_COMMAND, WndProc_OnCommand);

default:

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

}

}

// -----------------------------------------------------

// WndProc_OnCreate



// -----------------------------------------------------

BOOL WndProc_OnCreate(HWND hWnd,

LPCREATESTRUCT lpCreateStruct)

{

//

fTerminate = FALSE;

// ,

//

hThreads[0] = (HANDLE)_beginthread(PaintEllipse,

0, (void*)hWnd);

hThreads[1] = (HANDLE)_beginthread(PaintRect,

0, (void*)hWnd);

hThreads[2] = (HANDLE)_beginthread(PaintText,

0, (void*)hWnd);

return TRUE;

}

// -----------------------------------------------------

// WndProc_OnDestroy

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnDestroy(HWND hWnd)

{

//

fTerminate = TRUE;

//

WaitForMultipleObjects(3, hThreads, TRUE, INFINITE);



//

// Mutex

CloseHandle(hMutex);



// ,

//

PostQuitMessage(0);

return 0L;

}

// -----------------------------------------------------

// WndProc_OnPaint

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnPaint(HWND hWnd)

{

HDC hdc;

PAINTSTRUCT ps;

RECT rc;

DWORD dwRetCode;

// , Mutex

//

dwRetCode = WaitForSingleObject(hMutex, INFINITE);



// ,

if(dwRetCode == WAIT_OBJECT_0)

{

//

hdc = BeginPaint(hWnd, &ps);

GetClientRect(hWnd, &rc);

DrawText(hdc, "SDI Window", -1, &rc,

DT_SINGLELINE | DT_CENTER | DT_VCENTER);

EndPaint(hWnd, &ps);

// Mutex

ReleaseMutex(hMutex);



}

return 0;

}

// -----------------------------------------------------

// WndProc_OnCommand

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnCommand(HWND hWnd, int id,

HWND hwndCtl, UINT codeNotify)

{

switch (id)

{

case ID_FILE_EXIT:

{

//

PostQuitMessage(0);

return 0L;

break;

}



case ID_HELP_ABOUT:

{

MessageBox(hWnd,

"Multithread SDI Application with Mutex\n"

"(C) Alexandr Frolov, 1996\n"

"Email: frolov@glas.apc.org",

szAppTitle, MB_OK | MB_ICONINFORMATION);

return 0L;

break;

}

default:

break;

}

return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify,

DefWindowProc);

}

// -----------------------------------------------------

// PaintEllipse

// -----------------------------------------------------

void PaintEllipse(void *hwnd)

{

HDC hDC;

RECT rect;

LONG xLeft, xRight, yTop, yBottom;

short nRed, nGreen, nBlue;

HBRUSH hBrush, hOldBrush;

DWORD dwRetCode;

srand((unsigned int)hwnd);

while(!fTerminate)

{

// , Mutex

//

dwRetCode = WaitForSingleObject(hMutex, INFINITE);



// ,

if(dwRetCode == WAIT_OBJECT_0)

{

hDC = GetDC(hwnd);

nRed = rand() % 255;

nGreen = rand() % 255;

nBlue = rand() % 255;



GetWindowRect(hwnd, &rect);



xLeft = rand() % (rect.left + 1);

xRight = rand() % (rect.right + 1);

yTop = rand() % (rect.top + 1);

yBottom = rand() % (rect.bottom + 1);

hBrush = CreateSolidBrush(RGB(nRed, nGreen, nBlue));

hOldBrush = SelectObject(hDC, hBrush);



Ellipse(hDC, min(xLeft, xRight), min(yTop, yBottom),

max(xLeft, xRight), max(yTop, yBottom));

SelectObject(hDC, hOldBrush);

DeleteObject(hBrush);

ReleaseDC(hwnd, hDC);

ReleaseMutex(hMutex);

}

// ,

//

else

{

break;

}

Sleep(100);

}

}

// -----------------------------------------------------

// PaintRect

// -----------------------------------------------------

void PaintRect(void *hwnd)

{

HDC hDC;

RECT rect;

LONG xLeft, xRight, yTop, yBottom;

short nRed, nGreen, nBlue;

HBRUSH hBrush, hOldBrush;

DWORD dwRetCode;

srand((unsigned int)hwnd + 1);

while(!fTerminate)

{

dwRetCode = WaitForSingleObject(hMutex, INFINITE);

if(dwRetCode == WAIT_OBJECT_0)

{

hDC = GetDC(hwnd);

nRed = rand() % 255;

nGreen = rand() % 255;

nBlue = rand() % 255;

GetWindowRect(hwnd, &rect);

xLeft = rand() % (rect.left + 1);

xRight = rand() % (rect.right + 1);

yTop = rand() % (rect.top + 1);

yBottom = rand() % (rect.bottom + 1);

hBrush = CreateSolidBrush(RGB(nRed, nGreen, nBlue));

hOldBrush = SelectObject(hDC, hBrush);

Rectangle(hDC, min(xLeft, xRight), min(yTop, yBottom),

max(xLeft, xRight), max(yTop, yBottom));

SelectObject(hDC, hOldBrush);

DeleteObject(hBrush);

ReleaseDC(hwnd, hDC);

ReleaseMutex(hMutex);

}

else

{

break;

}

Sleep(100);

}

}

// -----------------------------------------------------

// PaintText

// -----------------------------------------------------

void PaintText(void *hwnd)

{

HDC hDC;

RECT rect;

LONG xLeft, xRight, yTop, yBottom;

short nRed, nGreen, nBlue;

DWORD dwRetCode;

srand((unsigned int)hwnd + 2);

while(!fTerminate)



{

dwRetCode = WaitForSingleObject(hMutex, INFINITE);

if(dwRetCode == WAIT_OBJECT_0)

{

hDC = GetDC(hwnd);

GetWindowRect(hwnd, &rect);

xLeft = rand() % (rect.left + 1);

xRight = rand() % (rect.right + 1);

yTop = rand() % (rect.top + 1);

yBottom = rand() % (rect.bottom + 1);

nRed = rand() % 255;

nGreen = rand() % 255;

nBlue = rand() % 255;

SetTextColor(hDC, RGB(nRed, nGreen, nBlue));

nRed = rand() % 255;

nGreen = rand() % 255;

nBlue = rand() % 255;

SetBkColor(hDC, RGB(nRed, nGreen, nBlue));

TextOut(hDC, xRight - xLeft,

yBottom - yTop,"TEXT", 4);

ReleaseDC(hwnd, hDC);

ReleaseMutex(hMutex);

}

else

{

break;

}

Sleep(100);

}

}

szMutexName, Mutex, . hMutex.

WinMain Mutex, CreateMutex, :

hMutex = CreateMutex(NULL, FALSE, szMutexName);

if(hMutex == NULL)

{

. . .

return 0l;

}

NULL. CreateMutex FALSE, Mutex .

CreateMutex ( NULL), , Mutex . GetLastError:

if(GetLastError() == ERROR_ALREADY_EXISTS)

{

MessageBox(NULL, "MutexSDI already started",

szAppTitle, MB_OK | MB_ICONEXCLAMATION);

return 0l;

}

ERROR_ALREADY_EXISTS, , Mutex szMutexName. .



. , .

WM_PAINT. WndProc_OnPaint.

, WaitForSingleObject, Mutex:

dwRetCode = WaitForSingleObject(hMutex, INFINITE);

, , , WaitForSingleObject , WAIT_OBJECT_0. WndProc_OnPaint , , Mutex , ReleaseMutex:

ReleaseMutex(hMutex);

, Mutex, .

, . . Mutex hMutex:

while(!fTerminate)

{

dwRetCode = WaitForSingleObject(hMutex, INFINITE);

if(dwRetCode == WAIT_OBJECT_0)

{

hDC = GetDC(hwnd);

. . .

Ellipse(hDC, min(xLeft, xRight), min(yTop, yBottom),

max(xLeft, xRight), max(yTop, yBottom));

. . .

ReleaseDC(hwnd, hDC);

ReleaseMutex(hMutex);

}

else

break;

Sleep(100);

}

Mutex, WaitForSingleObject WAIT_OBJECT_0. . - Mutex, . , .



Mutex ReleaseMutex.

, MutexSDI.

mutexsdi.h ( 4.4) , .

4.4. mutexsdi/mutexsdi.h

LRESULT WINAPI

WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

BOOL WndProc_OnCreate(HWND hWnd,

LPCREATESTRUCT lpCreateStruct);

void WndProc_OnDestroy(HWND hWnd);

void WndProc_OnPaint(HWND hWnd);

void WndProc_OnCommand(HWND hWnd, int id,

HWND hwndCtl, UINT codeNotify);

void PaintEllipse(void *hwnd);

void PaintRect(void *hwnd);

void PaintText(void *hwnd);

resource.h ( 4.5) .

4.5. mutexsdi/resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by MutexSDI.RC

//

#define IDR_APPMENU 102

#define IDI_APPICON 103

#define IDI_APPICONSM 104

#define ID_FILE_EXIT 40001

#define ID_HELP_ABOUT 40003

#define ID_FORMAT_BOLD 40010

#define ID_FORMAT_ITALIC 40011

#define ID_FORMAT_UNDERLINE 40012

#define ID_FORMAT_PARAGRAPH_LEFT 40014

#define ID_FORMAT_PARAGRAPH_RIGHT 40015

#define ID_FORMAT_PARAGRAPH_CENTER 40016

#define ID_EDIT_DELETE 40021

#define ID_FILE_SAVEAS 40024

#define ID_EDIT_SELECTALL 40028

#define ID_SETPROTECTION_PAGENOACCESS 40035

#define ID_SETPROTECTION_PAGEREADONLY 40036

#define ID_SETPROTECTION_PAGEREADWRITE 40037

#define ID_SETPROTECTION_PAGEGUARD 40038

#define ID_MEMORY_READ 40039

#define ID_MEMORY_WRITE 40040

#define ID_MEMORY_LOCK 40041

#define ID_MEMORY_UNLOCK 40042



// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE 121

#define _APS_NEXT_COMMAND_VALUE 40043

#define _APS_NEXT_CONTROL_VALUE 1000

#define _APS_NEXT_SYMED_VALUE 101

#endif

#endif

, , mutexsdi.rc  4.6.

4.6. mutexsdi/mutexsdi.rc

//Microsoft Developer Studio generated resource script.

//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

// Generated from the TEXTINCLUDE 2 resource.

//

#include "afxres.h"

//////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) defined(AFX_TARG_ENU)

#ifdef _WIN32

LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

#pragma code_page(1252)

#endif //_WIN32

//////////////////////////////////////////////////////////////

// Menu

//

IDR_APPMENU MENU DISCARDABLE

BEGIN

POPUP "&File"

BEGIN

MENUITEM "E&xit", ID_FILE_EXIT

END

POPUP "&Help"

BEGIN

MENUITEM "&About...", ID_HELP_ABOUT

END

END

#ifdef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

// TEXTINCLUDE

//

1 TEXTINCLUDE DISCARDABLE

BEGIN

"resource.h\0"

END

2 TEXTINCLUDE DISCARDABLE

BEGIN

"#include ""afxres.h""\r\n"

"\0"

END

3 TEXTINCLUDE DISCARDABLE

BEGIN

"\r\n"

"\0"

END

#endif // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

// Icon

//

// Icon with lowest ID value placed first to ensure

// application icon

// remains consistent on all systems.

IDI_APPICON ICON DISCARDABLE "mutexsdi.ico"

IDI_APPICONSM ICON DISCARDABLE "mutexssm.ico"

//////////////////////////////////////////////////////////////

// String Table

//

STRINGTABLE DISCARDABLE

BEGIN

ID_FILE_EXIT "Quits the application"

END

#endif // English (U.S.) resources

//////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

// Generated from the TEXTINCLUDE 3 resource.

//

//////////////////////////////////////////////////////////////

#endif // not APSTUDIO_INVOKED