1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
//Info passed to DoOperation thread
typedef struct {
int *pProgress;
HANDLE hMutex;
} OPERATION_INFO;
//Info passed to UpdateProgress thread
typedef struct {
int *pProgress;
HANDLE hMutex;
HWND hwndProgress;
} PROGRESS_INFO;
void DoOperation(LPVOID lpThreadParams) {
//Declare and initialize function variables
OPERATION_INFO *pOperationInfo = (OPERATION_INFO *)lpThreadParams;
int *pProgress = (*pOperationInfo).pProgress;
HANDLE hMutex = (*pOperationInfo).hMutex;
int i;
//Run a test loop
for (i=0; i<=100; i+=10) {
//Wait for mutex
WaitForSingleObject(hMutex,INFINITE);
//Update the progress and simulate a portion of a lengthy calculation
*pProgress = i;
Sleep(500);
//Release mutex
ReleaseMutex(hMutex);
}
}
void UpdateProgress(LPVOID lpThreadParams) {
//Declare and initialize function variables
PROGRESS_INFO *pProgressInfo = (PROGRESS_INFO *)lpThreadParams;
int* pProgress = (*pProgressInfo).pProgress;
HANDLE hMutex = (*pProgressInfo).hMutex;
HWND hwndProgress = (*pProgressInfo).hwndProgress;
//Monitor progress until complete
while (*pProgress < 100) {
//Wait for mutex
WaitForSingleObject(hMutex,INFINITE);
//Update the progress bar
//SendMessage(hwndProgress,PBM_SETPOS,(WPARAM)*pProgress,0);
PostMessage(hwndProgress,PBM_SETPOS,(WPARAM)*pProgress,0);
//Release the mutex
ReleaseMutex(hMutex);
}
//Finalize the progress
//SendMessage(hwndProgress,PBM_SETPOS,100,0);
PostMessage(hwndProgress,PBM_SETPOS,100,0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HWND hwndStart, hwndProgress;
static HANDLE hMutex;
static int nProgress = 0;
switch (message) {
case WM_CREATE:
{
//Initialize progress controls
INITCOMMONCONTROLSEX icce = { sizeof(INITCOMMONCONTROLSEX), ICC_PROGRESS_CLASS };
InitCommonControlsEx(&icce);
//Create the mutex
hMutex = CreateMutex(NULL,FALSE,NULL);
//Create the start button
hwndStart = CreateWindow(
"BUTTON", "Start", WS_CHILD | WS_VISIBLE, 300, 25, 50, 20,
hwnd, (HMENU)IDC_START, NULL, NULL
);
//Create the progress control
hwndProgress = CreateWindow(
PROGRESS_CLASS,NULL,WS_CHILD|WS_VISIBLE|PBS_SMOOTH, 25,25,200,20,
hwnd, (HMENU)IDC_PROGRESS, NULL, NULL
);
//Set the progress bar range and initial position
SendMessage(hwndProgress,PBM_SETRANGE32,0,100);
SendMessage(hwndProgress,PBM_SETPOS,0,0);
break;
}
case WM_COMMAND:
if (LOWORD(wParam) == IDC_START) {
//Declare and initialize thread variables
OPERATION_INFO operationInfo = { &nProgress, hMutex };
PROGRESS_INFO progressInfo = { &nProgress, hMutex, hwndProgress };
HANDLE threads[2];
//Begin threads
threads[0] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DoOperation,(LPVOID)&operationInfo,0,0);
threads[1] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)UpdateProgress,(LPVOID)&progressInfo,0,0);
//Wait for threads to finish
WaitForMultipleObjects(2,threads,TRUE,INFINITE);
//Clean up
CloseHandle(threads[0]);
CloseHandle(threads[1]);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
MSG msg;
HWND hwnd;
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszClassName = "MAIN";
wcex.hIconSm = LoadIcon(NULL,IDC_ARROW);
RegisterClassEx(&wcex);
hwnd = CreateWindow(
"MAIN", "Progress Bar Test App", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 100, NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
|