Voor een project dat 3 motoren op een CANbus aanstuurt moest ik nog een visualisatie maken, ik heb alles geschreven in MS Visual Studio 6. Alles gebeurd met API calls, en er is geen ATL, WTL of MFC etc. gebruikt. Nu had ik lang geleden wel eens wat grafische dingen geprogged in C, en heb me daarop nu terug gebasseerd. Ik kan echter mijn Win32 API Programming book van Charles Petzold niet terugvinden, en kan de fout zo meteen niet vinden. Ook niet na msdn over device contexts door te lezen..
De software is volledig af en werkte perfect, tot we het een nacht door lieten draaien. Alle functionaliteit blijft, enkel wordt er niets meer geupdate op het scherm, en uiteindelijk wordt het window gewoon zwart.
Door super veel commando's naar de liften te sturen, wat veel InvalidateRect's tot gevolg heeft, treed het probleem al op na 20min.
Hier volgt de WM_PAINT msg handler en andere relevante code, ik hoop dat iemand hier me kan vertellen wat ik verkeerd doe..
Ondertussen draait alles al bijna 45min zonder problemen nadat ik alles van de background drawen tot en met de right can bus drawen gecomment heb ... dus het probleem zit dan wss toch ergens in deze methode van bitmaps tekenen ? :
De software is volledig af en werkte perfect, tot we het een nacht door lieten draaien. Alle functionaliteit blijft, enkel wordt er niets meer geupdate op het scherm, en uiteindelijk wordt het window gewoon zwart.
Door super veel commando's naar de liften te sturen, wat veel InvalidateRect's tot gevolg heeft, treed het probleem al op na 20min.
Hier volgt de WM_PAINT msg handler en andere relevante code, ik hoop dat iemand hier me kan vertellen wat ik verkeerd doe..
C++:
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
| // global vars HBITMAP hImgBack; // Background Image Handle HBITMAP hImgLiftRed; // Red Lift Image Handle HBITMAP hImgLiftGreen; // Green Lift Image Handle ... ... // Application Entry Point int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (!LoadConfig()) { MessageBox(NULL, _T("Error reading configuration from registry."), _T("Config Error"), MB_OK); return FALSE; } if (!Comm_Init()) return FALSE; if (!Can_Init()) return FALSE; // Init Lifts Lifts_Init(); // Set screen resolution to 800x600 DEVMODE dvmd; EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dvmd); devModeDefault = dvmd; // Save original devmode dvmd.dmPelsWidth = 800; dvmd.dmPelsHeight = 600; dvmd.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; ChangeDisplaySettings(&dvmd, 0); // Load Bitmaps hImgBack = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP_BACK)); hImgLiftRed = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP_LIFTRED)); hImgLiftGreen = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP_LIFTGREEN)); ... ... LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc, hdcMap; HPEN hpSolid, hpOld; HFONT hfnt, hfntPrev; HGDIOBJ hgdi; PLOGFONT plf; RECT rt; switch (message) { ... ... case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // Fill background with black GetClientRect(hWnd, &rt); FillRect(hdc, &rt, (HBRUSH)GetStockObject(BLACK_BRUSH)); // Draw Background Bitmap hdcMap = CreateCompatibleDC(hdc); hgdi = SelectObject(hdcMap,hImgBack); BitBlt(hdc, 0,0,800,600,hdcMap,0,0,SRCCOPY); SelectObject(hdcMap,hgdi); //ReleaseDC(hWnd, hdcMap); // Draw Left Lift //hdcMap = CreateCompatibleDC(hdc); hgdi = SelectObject(hdcMap,(Lift[LIFT_LEFT].Status<2)?hImgLiftRed:hImgLiftGreen); if (!(((Lift[LIFT_LEFT].Status==LIFT_STAT_MOVING)||(Lift[LIFT_LEFT].Status==LIFT_STAT_HOMERUN))&&(bBlink))) BitBlt(hdc, Lift[LIFT_LEFT].xpos, LIFT_LEFT_YPOS,43,32, hdcMap,0,0,SRCCOPY); SelectObject(hdcMap,hgdi); //ReleaseDC(hWnd, hdcMap); // Draw Middle Lift //hdcMap = CreateCompatibleDC(hdc); hgdi = SelectObject(hdcMap,(Lift[LIFT_MIDDLE].Status<2)?hImgLiftRed:hImgLiftGreen); if (!(((Lift[LIFT_MIDDLE].Status==LIFT_STAT_MOVING)||(Lift[LIFT_MIDDLE].Status==LIFT_STAT_HOMERUN))&&(bBlink))) BitBlt(hdc, Lift[LIFT_MIDDLE].xpos,LIFT_MIDDLE_YPOS,43,32, hdcMap,0,0,SRCCOPY); SelectObject(hdcMap,hgdi); //ReleaseDC(hWnd, hdcMap); // Draw Right Lift //hdcMap = CreateCompatibleDC(hdc); hgdi = SelectObject(hdcMap,(Lift[LIFT_RIGHT].Status<2)?hImgLiftRed:hImgLiftGreen); if (!(((Lift[LIFT_RIGHT].Status==LIFT_STAT_MOVING)||(Lift[LIFT_RIGHT].Status==LIFT_STAT_HOMERUN))&&(bBlink))) BitBlt(hdc, Lift[LIFT_RIGHT].xpos,LIFT_RIGHT_YPOS,43,32, hdcMap,0,0,SRCCOPY); SelectObject(hdcMap,hgdi); ReleaseDC(hWnd, hdcMap); // Draw Left CAN Bus hpSolid = (HPEN)CreatePen(PS_SOLID, 1, (Lift[LIFT_LEFT].Status==LIFT_STAT_OFFLINE)?crRed:crGreen); hpOld = (HPEN)SelectObject(hdc, hpSolid); Polyline(hdc, ptLeftCanBus, 4); SelectObject(hdc, hpOld); DeleteObject((HPEN)hpSolid); // Draw Middle CAN Bus hpSolid = (HPEN)CreatePen(PS_SOLID, 1, (Lift[LIFT_MIDDLE].Status==LIFT_STAT_OFFLINE)?crRed:crGreen); hpOld = (HPEN)SelectObject(hdc, hpSolid); Polyline(hdc, ptMiddleCanBus, 2); SelectObject(hdc, hpOld); DeleteObject((HPEN)hpSolid); // Draw Right CAN Bus hpSolid = (HPEN)CreatePen(PS_SOLID, 1, (Lift[LIFT_RIGHT].Status==LIFT_STAT_OFFLINE)?crRed:crGreen); hpOld = (HPEN)SelectObject(hdc, hpSolid); Polyline(hdc, ptRightCanBus, 4); SelectObject(hdc, hpOld); DeleteObject((HPEN)hpSolid); // (Re-)Draw Top-Line of Control unit hpSolid = (HPEN)CreatePen(PS_SOLID, 1, RGB(255,255,255)); hpOld = (HPEN)SelectObject(hdc, hpSolid); Polyline(hdc, ptTopController, 2); SelectObject(hdc, hpOld); DeleteObject((HPEN)hpSolid); // Draw -Controller- in red when UART controlpanel is offline if (!bMainPanelOnline) { hpSolid = (HPEN)CreatePen(PS_SOLID, 1, crRed); hpOld = (HPEN)SelectObject(hdc, hpSolid); Polyline(hdc, ptMainPanel, 5); SelectObject(hdc, hpOld); DeleteObject((HPEN)hpSolid); } // Write Texts // Init Font for vertical orientation plf = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT)); memcpy(plf->lfFaceName, "Arial", 6 ); plf->lfWeight = FW_NORMAL; plf->lfEscapement = 900; plf->lfHeight = 9; hfnt = CreateFontIndirect(plf); hfntPrev = (HFONT)SelectObject(hdc, hfnt); SetBkColor(hdc, RGB(0,0,0)); // Write Status for Left Lift SetTextColor(hdc, ((Lift[LIFT_LEFT].Status<2)?crRed:crGreen)); TextOut(hdc, rtTextLeftLift.left, rtTextLeftLift.bottom, Lift[LIFT_LEFT].szStatusMsg, strlen(Lift[LIFT_LEFT].szStatusMsg)); // Write Status for Middle Lift SetTextColor(hdc, ((Lift[LIFT_MIDDLE].Status<2)?crRed:crGreen)); TextOut(hdc, rtTextMiddleLift.left, rtTextMiddleLift.bottom, Lift[LIFT_MIDDLE].szStatusMsg, strlen(Lift[LIFT_MIDDLE].szStatusMsg)); // Write Status for Right Lift SetTextColor(hdc, ((Lift[LIFT_RIGHT].Status<2)?crRed:crGreen)); TextOut(hdc, rtTextRightLift.left, rtTextRightLift.bottom, Lift[LIFT_RIGHT].szStatusMsg, strlen(Lift[LIFT_RIGHT].szStatusMsg)); // Write Remote Panels ON/OFF TCHAR szRemotePanelOnOff[10]; wsprintf(szRemotePanelOnOff, (bRemotePanelEnable)?_T("ON"):_T("OFF")); SetTextColor(hdc, RGB(255,255,255)); TextOut(hdc, rtTextRemoteLeft.left, rtTextRemoteLeft.bottom, _T("REMOTE"), 6); TextOut(hdc, rtTextRemoteLeft.left + 9, rtTextRemoteLeft.bottom - 10, szRemotePanelOnOff, strlen(szRemotePanelOnOff)); TextOut(hdc, rtTextRemoteRight.left, rtTextRemoteRight.bottom, _T("REMOTE"), 6); TextOut(hdc, rtTextRemoteRight.left + 9, rtTextRemoteRight.bottom - 10, szRemotePanelOnOff, strlen(szRemotePanelOnOff)); // Set Previous Font & Delete SelectObject(hdc, hfntPrev); DeleteObject(hfnt); LocalFree((LOCALHANDLE) plf); EndPaint(hWnd, &ps); break; |
Ondertussen draait alles al bijna 45min zonder problemen nadat ik alles van de background drawen tot en met de right can bus drawen gecomment heb ... dus het probleem zit dan wss toch ergens in deze methode van bitmaps tekenen ? :
C++:
1
2
3
4
5
6
7
| // Draw Right Lift hdcMap = CreateCompatibleDC(hdc); hgdi = SelectObject(hdcMap,(Lift[LIFT_RIGHT].Status<2)?hImgLiftRed:hImgLiftGreen); if (((Lift[LIFT_RIGHT].Status==LIFT_STAT_MOVING)||(Lift[LIFT_RIGHT].Status==LIFT_STAT_HOMERUN))&&(bBlink))) BitBlt(hdc, Lift[LIFT_RIGHT].xpos,LIFT_RIGHT_YPOS,43,32, hdcMap,0,0,SRCCOPY); SelectObject(hdcMap,hgdi); ReleaseDC(hWnd, hdcMap); |