EDN Admin
Well-known member
Hi,
I have a program that draws a circle in the main window, when a user presses a key on the keyboard. Every circle has a timer in it, that counts down to zero and then the circle disappears.
I put all the relevant pieces of code below.
In the beginning, function circle() is called that starts a thread updating the main window. Function setCircle() is called every time a certain key is pressed to add a new circle to the current pool.
<pre class="prettyprint" style=" typedef struct circleStructure {
int x;
int y;
int timer;
int r;
RECT rect;
int id;
} FSTRUCT, *PFSTRUCT;
PFSTRUCT FS[20] = {NULL}; bool CIRCLING = false;<br/>char timestamp[9];<br/>HPEN emptyPen = (HPEN)GetStockObject(NULL_PEN);<br/> [/code]
<br/>
<pre class="prettyprint" style=" ...
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if(CIRCLING) {
drawCircles();
}
EndPaint(hWnd, &ps);
break;
...[/code]
<br/>
<pre class="prettyprint" style=" DWORD WINAPI threadCircle(LPVOID param) {
PFSTRUCT pF;
pF = (PFSTRUCT)param;
for(;pF->timer>-2;pF->timer--) {
_strtime_s(timestamp,9);
*circleFile << timestamp << " threadCircle[" << pF->id << "] timer:" << pF->timer << "n";
Sleep(1000);
}
pF->timer++;
_strtime_s(timestamp,9);
*circleFile << timestamp << " threadCircle[" << pF->id << "] timer:" << pF->timer << " overn";
return 0;
}
DWORD WINAPI threadCircleUpdate() {
RECT vp;
GetClientRect(hStats, &vp);
vp.left+=11;
vp.right+=11;
vp.top+=41;
vp.bottom+=41;
while(CIRCLING) {
Sleep(500);
InvalidateRect(hWnd, &vp, FALSE);
UpdateWindow(hWnd);
}
return 0;
}
void circle() { CIRCLING = true;
if(circleFile == NULL) {
circleFile = new ofstream();
circleFile->open("circle.txt", ios::ate | ios::app);
}
if(FS[0] == NULL) {
for(int i=0;i<20;i++) {
FS = new FSTRUCT();
}
}
for(int i=0;i<20;i++) {
FS->timer = -1;
FS->r = 25;
FS->id = i;
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadCircleUpdate, NULL, 0, NULL);
}
void setCircle(WPARAM wParam) {
POINT curp;
GetCursorPos(&curp);
ScreenToClient(hWnd, &curp);
RECT vp;
GetClientRect(hStats, &vp);
vp.left+=11;
vp.right+=11;
vp.top+=41;
vp.bottom+=41;
if(curp.x > vp.left && curp.x < vp.right && curp.y > vp.top && curp.y < vp.bottom) {
int delay, curI;
for(int i=0;i<20;i++) {
if(FS->timer == -1) {
curI = i;
break;
}
}
_strtime_s(timestamp,9);
*circleFile << timestamp << " found free index: " << curI << "n";
if(wParam == 0x31) {
FS[curI]->timer = 50;
} else if(wParam == 0x32) {
FS[curI]->timer = 46;
}
_strtime_s(timestamp,9);
*circleFile << timestamp << " timer set: " << FS[curI]->timer << "n";
FS[curI]->x = curp.x;
FS[curI]->y = curp.y;
FS[curI]->rect.left = FS[curI]->x - FS[curI]->r;
FS[curI]->rect.right = FS[curI]->x + FS[curI]->r;
FS[curI]->rect.top = FS[curI]->y - FS[curI]->r;
FS[curI]->rect.bottom = FS[curI]->y + FS[curI]->r;
_strtime_s(timestamp,9);
*circleFile << timestamp << " create threadCircle " << FS[curI]->id
<< "[" << FS[curI]->timer << "," << FS[curI]->x << "," << FS[curI]->y << "]n";
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadCircle, FS[curI], 0, NULL);
} else {
*circleFile << "Circle creation rejected.n";
}
}
void drawCircles() {
if(FS[0] != NULL) {
_strtime_s(timestamp,9);
*circleFile << timestamp << " drawCircles: ";
HBRUSH oldBrush, fBrush[2] = {CreateSolidBrush(RGB(150,50,150)),CreateSolidBrush(RGB(150,50,50))};
HDC hWndDC = GetDC(hWnd);
*circleFile << "assigning empty pen: " << emptyPen << "...n";
HPEN oldPen = (HPEN)SelectObject(hWndDC,emptyPen);
*circleFile << "oldP: " << oldPen << ", ";
if(oldPen == NULL) {
DWORD lastError = GetLastError();
*circleFile << "GENERAL FAILURE. GetLastError returned 0x" << setbase(16) << lastError << setbase(10) << "n";
}
SetTextColor(hWndDC,RGB(255,255,255));
SetBkMode(hWndDC, TRANSPARENT);
SetTextAlign(hWndDC, TA_CENTER | TA_BASELINE);
char ch[21];
for(int i=0;i<20;i++) {
if(FS->timer != -1) {
if(FS->timer>5) {
oldBrush = (HBRUSH)SelectObject(hWndDC,fBrush[0]);
} else {
oldBrush = (HBRUSH)SelectObject(hWndDC,fBrush[1]);
}
*circleFile << "oldB: " << oldBrush << ", ";
*circleFile << FS->id << "[" << FS->timer << "," << FS->x << "," << FS->y << "] ";
int length = sprintf_s(ch,"%d",FS->timer);
Ellipse(hWndDC, FS->rect.left, FS->rect.top, FS->rect.right, FS->rect.bottom);
TextOut(hWndDC,FS->x, FS->y+4, ch, length);
SelectObject(hWndDC,oldBrush);
}
}
SelectObject(hWndDC,oldPen);
*circleFile << " ...done.n";
}
} [/code]
The problem is that after certain quite a long amount of time and many circle created and gone, all current circles suddenly disappear from the screen.
I found the source of the problem - function SelectObject() starts returning a NULL pen, so the log file "circle.txt" goes like this:
<pre class="prettyprint" style=" ... 12:34:39 threadCircle[3] timer:28
12:34:39 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[21,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:39 drawCircles: 12:34:39 threadCircle[0] timer:20
assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[20,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:39 global keypress: 0x54
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[20,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[20,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:40 global keypress: 0x54
12:34:40 threadCircle[3] timer:27
12:34:40 threadCircle[0] timer:19
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[19,227,178] oldB: 0000000001900010, 3[27,150,420] ...done.
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[19,227,178] oldB: 0000000001900010, 3[27,150,420] ...done.
12:34:41 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[19,227,178] oldB: 0000000001900010, 3[27,150,420] ...done.
12:34:41 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000000000000, GENERAL FAILURE. GetLastError returned 0x6
oldB: 0000000000000000, 0[19,227,178] oldB: 0000000000000000, 3[27,150,420] ...done.
12:34:41 threadCircle[3] timer:26
12:34:41 threadCircle[0] timer:18
12:34:41 global keypress: 0x54
12:34:41 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000000000000, GENERAL FAILURE. GetLastError returned 0x6
oldB: 0000000000000000, 0[18,227,178] oldB: 0000000000000000, 3[26,150,420] ...done.
12:34:41 drawCircles: assigning empty pen: 0000000001B00016... ... [/code]
I dont understand why it could possibly happen, so any help would be appreciated.
Thanks!
<br/>
<br/>
View the full article
I have a program that draws a circle in the main window, when a user presses a key on the keyboard. Every circle has a timer in it, that counts down to zero and then the circle disappears.
I put all the relevant pieces of code below.
In the beginning, function circle() is called that starts a thread updating the main window. Function setCircle() is called every time a certain key is pressed to add a new circle to the current pool.
<pre class="prettyprint" style=" typedef struct circleStructure {
int x;
int y;
int timer;
int r;
RECT rect;
int id;
} FSTRUCT, *PFSTRUCT;
PFSTRUCT FS[20] = {NULL}; bool CIRCLING = false;<br/>char timestamp[9];<br/>HPEN emptyPen = (HPEN)GetStockObject(NULL_PEN);<br/> [/code]
<br/>
<pre class="prettyprint" style=" ...
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if(CIRCLING) {
drawCircles();
}
EndPaint(hWnd, &ps);
break;
...[/code]
<br/>
<pre class="prettyprint" style=" DWORD WINAPI threadCircle(LPVOID param) {
PFSTRUCT pF;
pF = (PFSTRUCT)param;
for(;pF->timer>-2;pF->timer--) {
_strtime_s(timestamp,9);
*circleFile << timestamp << " threadCircle[" << pF->id << "] timer:" << pF->timer << "n";
Sleep(1000);
}
pF->timer++;
_strtime_s(timestamp,9);
*circleFile << timestamp << " threadCircle[" << pF->id << "] timer:" << pF->timer << " overn";
return 0;
}
DWORD WINAPI threadCircleUpdate() {
RECT vp;
GetClientRect(hStats, &vp);
vp.left+=11;
vp.right+=11;
vp.top+=41;
vp.bottom+=41;
while(CIRCLING) {
Sleep(500);
InvalidateRect(hWnd, &vp, FALSE);
UpdateWindow(hWnd);
}
return 0;
}
void circle() { CIRCLING = true;
if(circleFile == NULL) {
circleFile = new ofstream();
circleFile->open("circle.txt", ios::ate | ios::app);
}
if(FS[0] == NULL) {
for(int i=0;i<20;i++) {
FS = new FSTRUCT();
}
}
for(int i=0;i<20;i++) {
FS->timer = -1;
FS->r = 25;
FS->id = i;
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadCircleUpdate, NULL, 0, NULL);
}
void setCircle(WPARAM wParam) {
POINT curp;
GetCursorPos(&curp);
ScreenToClient(hWnd, &curp);
RECT vp;
GetClientRect(hStats, &vp);
vp.left+=11;
vp.right+=11;
vp.top+=41;
vp.bottom+=41;
if(curp.x > vp.left && curp.x < vp.right && curp.y > vp.top && curp.y < vp.bottom) {
int delay, curI;
for(int i=0;i<20;i++) {
if(FS->timer == -1) {
curI = i;
break;
}
}
_strtime_s(timestamp,9);
*circleFile << timestamp << " found free index: " << curI << "n";
if(wParam == 0x31) {
FS[curI]->timer = 50;
} else if(wParam == 0x32) {
FS[curI]->timer = 46;
}
_strtime_s(timestamp,9);
*circleFile << timestamp << " timer set: " << FS[curI]->timer << "n";
FS[curI]->x = curp.x;
FS[curI]->y = curp.y;
FS[curI]->rect.left = FS[curI]->x - FS[curI]->r;
FS[curI]->rect.right = FS[curI]->x + FS[curI]->r;
FS[curI]->rect.top = FS[curI]->y - FS[curI]->r;
FS[curI]->rect.bottom = FS[curI]->y + FS[curI]->r;
_strtime_s(timestamp,9);
*circleFile << timestamp << " create threadCircle " << FS[curI]->id
<< "[" << FS[curI]->timer << "," << FS[curI]->x << "," << FS[curI]->y << "]n";
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadCircle, FS[curI], 0, NULL);
} else {
*circleFile << "Circle creation rejected.n";
}
}
void drawCircles() {
if(FS[0] != NULL) {
_strtime_s(timestamp,9);
*circleFile << timestamp << " drawCircles: ";
HBRUSH oldBrush, fBrush[2] = {CreateSolidBrush(RGB(150,50,150)),CreateSolidBrush(RGB(150,50,50))};
HDC hWndDC = GetDC(hWnd);
*circleFile << "assigning empty pen: " << emptyPen << "...n";
HPEN oldPen = (HPEN)SelectObject(hWndDC,emptyPen);
*circleFile << "oldP: " << oldPen << ", ";
if(oldPen == NULL) {
DWORD lastError = GetLastError();
*circleFile << "GENERAL FAILURE. GetLastError returned 0x" << setbase(16) << lastError << setbase(10) << "n";
}
SetTextColor(hWndDC,RGB(255,255,255));
SetBkMode(hWndDC, TRANSPARENT);
SetTextAlign(hWndDC, TA_CENTER | TA_BASELINE);
char ch[21];
for(int i=0;i<20;i++) {
if(FS->timer != -1) {
if(FS->timer>5) {
oldBrush = (HBRUSH)SelectObject(hWndDC,fBrush[0]);
} else {
oldBrush = (HBRUSH)SelectObject(hWndDC,fBrush[1]);
}
*circleFile << "oldB: " << oldBrush << ", ";
*circleFile << FS->id << "[" << FS->timer << "," << FS->x << "," << FS->y << "] ";
int length = sprintf_s(ch,"%d",FS->timer);
Ellipse(hWndDC, FS->rect.left, FS->rect.top, FS->rect.right, FS->rect.bottom);
TextOut(hWndDC,FS->x, FS->y+4, ch, length);
SelectObject(hWndDC,oldBrush);
}
}
SelectObject(hWndDC,oldPen);
*circleFile << " ...done.n";
}
} [/code]
The problem is that after certain quite a long amount of time and many circle created and gone, all current circles suddenly disappear from the screen.
I found the source of the problem - function SelectObject() starts returning a NULL pen, so the log file "circle.txt" goes like this:
<pre class="prettyprint" style=" ... 12:34:39 threadCircle[3] timer:28
12:34:39 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[21,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:39 drawCircles: 12:34:39 threadCircle[0] timer:20
assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[20,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:39 global keypress: 0x54
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[20,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[20,227,178] oldB: 0000000001900010, 3[28,150,420] ...done.
12:34:40 global keypress: 0x54
12:34:40 threadCircle[3] timer:27
12:34:40 threadCircle[0] timer:19
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[19,227,178] oldB: 0000000001900010, 3[27,150,420] ...done.
12:34:40 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[19,227,178] oldB: 0000000001900010, 3[27,150,420] ...done.
12:34:41 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000001B00017, oldB: 0000000001900010, 0[19,227,178] oldB: 0000000001900010, 3[27,150,420] ...done.
12:34:41 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000000000000, GENERAL FAILURE. GetLastError returned 0x6
oldB: 0000000000000000, 0[19,227,178] oldB: 0000000000000000, 3[27,150,420] ...done.
12:34:41 threadCircle[3] timer:26
12:34:41 threadCircle[0] timer:18
12:34:41 global keypress: 0x54
12:34:41 drawCircles: assigning empty pen: 0000000001B00016...
oldP: 0000000000000000, GENERAL FAILURE. GetLastError returned 0x6
oldB: 0000000000000000, 0[18,227,178] oldB: 0000000000000000, 3[26,150,420] ...done.
12:34:41 drawCircles: assigning empty pen: 0000000001B00016... ... [/code]
I dont understand why it could possibly happen, so any help would be appreciated.
Thanks!
<br/>
<br/>
View the full article