1. /*
    2. This program is free software: you can redistribute it and/or modify
    3. it under the terms of the GNU General Public License as published by
    4. the Free Software Foundation, either version 3 of the License, or
    5. (at your option) any later version.
    6. This program is distributed in the hope that it will be useful,
    7. but WITHOUT ANY WARRANTY; without even the implied warranty of
    8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    9. GNU General Public License for more details.
    10. You should have received a copy of the GNU General Public License
    11. along with this program. If not, see <http://www.gnu.org/licenses/>.
    12. */
    13. ////////////////////////////////////////////////////////////////
    14. // ACLLib - Advanced C Lab Library
    15. // Ver. 2014-07
    16. // For Students' Lab at Zhejiang University
    17. // Created 2008 by Gao Yuan
    18. // Modified 2009 by Cui Liwei
    19. // 2010 by Lan Huidong
    20. // Revised 2012 by Li Rui
    21. // Modified 2014 by Weng Kai for MOOC
    22. ////////////////////////////////////////////////////////////////
    23. #define _CRT_SECURE_NO_WARNINGS
    24. #define _CRT_NON_CONFORMING_SWPRINTFS
    25. #define CINTERFACE
    26. #ifdef _UNICODE
    27. #undef _UNICODE
    28. #endif
    29. #ifdef UNICODE
    30. #undef UNICODE
    31. #endif
    32. #include "acllib.h"
    33. #include <windows.h>
    34. #include <olectl.h>
    35. #include <stdio.h>
    36. #ifdef _MSC_VER
    37. #pragma comment(lib,"winmm.lib")
    38. #pragma comment(lib,"msimg32.lib")
    39. #endif
    40. #ifdef _DEBUG
    41. #define ACL_ASSERT(_Expression,errStr) (void)( (!!(_Expression)) || (acl_error(errStr),0) )
    42. #else
    43. #define ACL_ASSERT(flag,errStr) ((void)0)
    44. #endif
    45. #define ACL_ASSERT_HWND ACL_ASSERT(g_hWnd!=0, \
    46. "You should call function \"initWindow(...)\" befor use function \"" __FUNCTION__ "\"" )
    47. #define ACL_ASSERT_BEGIN_PAINT ACL_ASSERT(g_hmemdc!=0, \
    48. "You should call function \"beginPaint()\" befor use function \"" __FUNCTION__ "\"" )
    49. // f
    50. int Setup(void);
    51. const char g_wndClassName[] = "ACL_WND_CLASS";
    52. const char g_libName[] = "ACLLIB";
    53. HINSTANCE g_hInstance;
    54. HWND g_hWnd = NULL;
    55. HDC g_hmemdc = NULL;
    56. HBITMAP g_hbitmap = NULL;
    57. int g_wndHeight;
    58. int g_wndWidth;
    59. HPEN g_pen = NULL;
    60. ACL_Color g_penColor = BLACK;
    61. int g_penWidth = 1;
    62. int g_penStyle = PEN_STYLE_SOLID;
    63. HBRUSH g_brush = NULL;
    64. ACL_Color g_brushColor = BLACK;
    65. int g_brushStyle = BRUSH_STYLE_SOLID;
    66. HFONT g_font = NULL;
    67. char g_fontName[256] = "宋体";
    68. int g_textSize = 12;
    69. ACL_Color g_textColor = BLACK;
    70. ACL_Color g_textBkColor = WHITE;
    71. int g_caretHeight = 12;
    72. int g_caretWidth = 6;
    73. int g_caretX = 0;
    74. int g_caretY = 0;
    75. int g_soundID = 0;
    76. KeyboardEventCallback g_keyboard = NULL;
    77. MouseEventCallback g_mouse = NULL;
    78. TimerEventCallback g_timer = NULL;
    79. CharEventCallback g_char = NULL;
    80. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    81. //
    82. void acl_error(char *errStr)
    83. {
    84. MessageBoxA(g_hWnd,errStr,g_libName,MB_ICONERROR);
    85. exit(0);
    86. }
    87. //
    88. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    89. {
    90. MSG msg;
    91. WNDCLASSA wndclass;
    92. g_hInstance = hInstance;
    93. g_hWnd = NULL;
    94. g_keyboard = NULL;
    95. g_mouse = NULL;
    96. g_timer = NULL;
    97. wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
    98. wndclass.lpfnWndProc = WndProc;
    99. wndclass.cbClsExtra = 0;
    100. wndclass.cbWndExtra = 0;
    101. wndclass.hInstance = hInstance;
    102. wndclass.hInstance = hInstance;
    103. wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    104. wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    105. wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    106. wndclass.lpszMenuName = NULL;
    107. wndclass.lpszClassName = g_wndClassName;
    108. if (!RegisterClassA(&wndclass))
    109. {
    110. MessageBoxA(NULL, "This program requires Windows NT!", g_libName, MB_ICONERROR);
    111. return 0;
    112. }
    113. Setup();
    114. ACL_ASSERT(g_hWnd,"You must call \"initWindow(...)\" in Main()");
    115. while (GetMessage(&msg, NULL, 0, 0))
    116. {
    117. TranslateMessage (&msg);
    118. DispatchMessage (&msg);
    119. }
    120. return msg.wParam;
    121. }
    122. //
    123. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    124. {
    125. switch (message)
    126. {
    127. case WM_CREATE:
    128. {
    129. HDC hdc;
    130. hdc = GetDC(hwnd);
    131. g_hbitmap = CreateCompatibleBitmap(
    132. hdc, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
    133. g_hmemdc = CreateCompatibleDC(hdc);
    134. SelectObject(g_hmemdc, g_hbitmap);
    135. BitBlt(g_hmemdc,
    136. 0, 0,
    137. GetSystemMetrics(SM_CXSCREEN),
    138. GetSystemMetrics(SM_CYSCREEN),
    139. g_hmemdc,
    140. 0, 0,
    141. WHITENESS);
    142. DeleteDC(g_hmemdc);
    143. ReleaseDC(hwnd, hdc);
    144. CreateCaret(hwnd,0,g_caretWidth,g_caretHeight);
    145. g_caretX = g_wndWidth;
    146. g_caretY = g_wndHeight;
    147. SetCaretPos(g_caretX,g_caretY);
    148. break;
    149. }
    150. case WM_ERASEBKGND:
    151. break;
    152. case WM_PAINT:
    153. {
    154. HDC hdc;
    155. PAINTSTRUCT ps;
    156. RECT rect;
    157. hdc = BeginPaint(hwnd, &ps);
    158. g_hmemdc = CreateCompatibleDC(hdc);
    159. SelectObject(g_hmemdc, g_hbitmap);
    160. GetClientRect(hwnd,&rect);
    161. BitBlt(hdc, 0, 0, rect.right - rect.left,
    162. rect.bottom - rect.top, g_hmemdc, 0, 0, SRCCOPY);
    163. DeleteDC(g_hmemdc);
    164. g_hmemdc = 0;
    165. EndPaint(hwnd,&ps);
    166. break;
    167. }
    168. case WM_CHAR:
    169. if (g_char != NULL)
    170. g_char((char) wParam);
    171. break;
    172. case WM_KEYDOWN:
    173. if (g_keyboard != NULL)
    174. g_keyboard((int) wParam,KEY_DOWN);
    175. break;
    176. case WM_KEYUP:
    177. if(g_keyboard != NULL)
    178. g_keyboard((int) wParam,KEY_UP);
    179. break;
    180. case WM_LBUTTONDOWN:
    181. if (g_mouse != NULL)
    182. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), LEFT_BUTTON, BUTTON_DOWN);
    183. break;
    184. case WM_LBUTTONUP:
    185. if (g_mouse != NULL)
    186. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), LEFT_BUTTON, BUTTON_UP);
    187. break;
    188. case WM_LBUTTONDBLCLK:
    189. if (g_mouse != NULL)
    190. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), LEFT_BUTTON, BUTTON_DOUBLECLICK);
    191. break;
    192. case WM_MBUTTONDOWN:
    193. if (g_mouse != NULL)
    194. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), MIDDLE_BUTTON, BUTTON_DOWN);
    195. break;
    196. case WM_MBUTTONUP:
    197. if (g_mouse != NULL)
    198. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), MIDDLE_BUTTON, BUTTON_UP);
    199. break;
    200. case WM_MBUTTONDBLCLK:
    201. if (g_mouse != NULL)
    202. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), MIDDLE_BUTTON, BUTTON_DOUBLECLICK);
    203. break;
    204. case WM_RBUTTONDOWN:
    205. if (g_mouse != NULL)
    206. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), RIGHT_BUTTON, BUTTON_DOWN);
    207. break;
    208. case WM_RBUTTONUP:
    209. if (g_mouse != NULL)
    210. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), RIGHT_BUTTON, BUTTON_UP);
    211. break;
    212. case WM_RBUTTONDBLCLK:
    213. if (g_mouse != NULL)
    214. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), RIGHT_BUTTON, BUTTON_DOUBLECLICK);
    215. break;
    216. case WM_MOUSEMOVE:
    217. if(g_mouse != NULL)
    218. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam), MOUSEMOVE, MOUSEMOVE);
    219. break;
    220. case WM_MOUSEWHEEL:
    221. if(g_mouse == NULL)
    222. break;
    223. if(HIWORD(wParam) == 120)
    224. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam),MIDDLE_BUTTON,ROLL_UP);
    225. else if(HIWORD(wParam)==65416)
    226. g_mouse((int) LOWORD(lParam), (int) HIWORD(lParam),MIDDLE_BUTTON,ROLL_DOWN);
    227. break;
    228. case WM_TIMER:
    229. if (g_timer != NULL)
    230. g_timer(wParam);
    231. break;
    232. case WM_DESTROY:
    233. DeleteObject(g_hbitmap);
    234. PostQuitMessage(0);
    235. break;
    236. default:
    237. return DefWindowProc(hwnd, message, wParam, lParam);
    238. }
    239. return 0;
    240. }
    241. //
    242. void initWindow(const char *wndName, int x, int y, int width, int height)
    243. {
    244. RECT rect;
    245. ACL_ASSERT(!g_hWnd,"Don't call initWindow twice");
    246. g_wndHeight = height;
    247. g_wndWidth = width;
    248. if(x==DEFAULT || y==DEFAULT)
    249. x=y=CW_USEDEFAULT;
    250. g_hWnd = CreateWindowA (
    251. g_wndClassName, wndName,
    252. WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_SIZEBOX,
    253. x, y,
    254. width, height,
    255. NULL, NULL, 0, NULL) ;
    256. if(!g_hWnd)
    257. {
    258. MessageBoxA(NULL,"Fail to create window",g_libName,MB_ICONERROR);
    259. exit(0);
    260. }
    261. GetClientRect(g_hWnd,&rect);
    262. width += width - (rect.right-rect.left);
    263. height += height - (rect.bottom-rect.top);
    264. SetWindowPos(g_hWnd,HWND_TOP,0,0,width,height,SWP_NOMOVE);
    265. ShowWindow (g_hWnd,1);
    266. UpdateWindow (g_hWnd);
    267. }
    268. void initConsole(void)
    269. {
    270. AllocConsole();
    271. freopen("CONIN$", "r+t", stdin);
    272. freopen("CONOUT$", "w+t", stdout);
    273. }
    274. void msgBox(const char title[],const char text[],int flag)
    275. {
    276. ACL_ASSERT_HWND;
    277. MessageBoxA(g_hWnd,text,title,flag);
    278. }
    279. //
    280. void updatePen();
    281. void updateBrush();
    282. void updateFont();
    283. //
    284. void beginPaint()
    285. {
    286. HDC hdc;
    287. ACL_ASSERT_HWND;
    288. hdc = GetDC(g_hWnd);
    289. g_hmemdc = CreateCompatibleDC(hdc);
    290. SelectObject(g_hmemdc,g_hbitmap);
    291. updatePen();
    292. updateBrush();
    293. updateFont();
    294. setTextColor(g_textColor);
    295. setTextBkColor(g_textBkColor);
    296. }
    297. void endPaint()
    298. {
    299. DeleteDC(g_hmemdc);
    300. g_hmemdc = 0;
    301. InvalidateRect(g_hWnd,0,0);
    302. DeleteObject(g_pen);
    303. DeleteObject(g_brush);
    304. DeleteObject(g_font);
    305. g_pen = NULL;
    306. g_brush = NULL;
    307. g_font = NULL;
    308. }
    309. void clearDevice(void)
    310. {
    311. ACL_ASSERT_BEGIN_PAINT;
    312. BitBlt(
    313. g_hmemdc,
    314. 0, 0,
    315. GetSystemMetrics(SM_CXSCREEN),
    316. GetSystemMetrics(SM_CYSCREEN) ,
    317. g_hmemdc,
    318. 0, 0,
    319. WHITENESS);
    320. }
    321. void updatePen()
    322. {
    323. if(g_pen)DeleteObject(g_pen);
    324. if(g_penColor==EMPTY)
    325. g_pen = (HPEN)GetStockObject(NULL_PEN);
    326. else
    327. g_pen = CreatePen(g_penStyle,g_penWidth,g_penColor);
    328. SelectObject(g_hmemdc,g_pen);
    329. }
    330. void updateBrush()
    331. {
    332. if(g_brush)DeleteObject(g_brush);
    333. if(g_brushColor==EMPTY)
    334. {
    335. g_brush = (HBRUSH)GetStockObject(NULL_BRUSH);
    336. }
    337. else
    338. {
    339. if(g_brushStyle==BRUSH_STYLE_SOLID)
    340. g_brush = CreateSolidBrush(g_brushColor);
    341. else
    342. g_brush = CreateHatchBrush(g_brushStyle,g_brushColor);
    343. }
    344. SelectObject(g_hmemdc,g_brush);
    345. }
    346. void updateFont()
    347. {
    348. if(g_font)DeleteObject(g_font);
    349. g_font = CreateFontA(
    350. g_textSize,
    351. 0,
    352. 0,0,700,0,0,0,0,0,0,0,0,g_fontName);
    353. SelectObject(g_hmemdc,g_font);
    354. }
    355. void setPenColor(ACL_Color newColor)
    356. {
    357. ACL_ASSERT_BEGIN_PAINT;
    358. g_penColor = newColor;
    359. updatePen();
    360. }
    361. void setPenWidth(int width)
    362. {
    363. ACL_ASSERT_BEGIN_PAINT;
    364. g_penWidth = width;
    365. updatePen();
    366. }
    367. void setPenStyle(ACL_Pen_Style newStyle)
    368. {
    369. ACL_ASSERT_BEGIN_PAINT;
    370. switch(newStyle)
    371. {
    372. case PEN_STYLE_SOLID:
    373. g_penStyle = PS_SOLID; break;
    374. case PEN_STYLE_DASH:
    375. g_penStyle = PS_DASH; break;
    376. case PEN_STYLE_DOT:
    377. g_penStyle = PS_DOT; break;
    378. case PEN_STYLE_DASHDOT:
    379. g_penStyle = PS_DASHDOT; break;
    380. case PEN_STYLE_DASHDOTDOT:
    381. g_penStyle = PS_DASHDOTDOT; break;
    382. case PEN_STYLE_NULL:
    383. g_penStyle = -1;
    384. setPenColor(EMPTY);
    385. return;
    386. default:
    387. break;
    388. }
    389. updatePen();
    390. }
    391. void setBrushColor(ACL_Color newColor)
    392. {
    393. ACL_ASSERT_BEGIN_PAINT;
    394. g_brushColor = newColor;
    395. updateBrush();
    396. }
    397. void setBrushStyle(ACL_Brush_Style newStyle)
    398. {
    399. ACL_ASSERT_BEGIN_PAINT;
    400. switch(newStyle)
    401. {
    402. case BRUSH_STYLE_SOLID:
    403. g_brushStyle = BRUSH_STYLE_SOLID; break;
    404. case BRUSH_STYLE_HORIZONTAL:
    405. g_brushStyle = HS_HORIZONTAL; break;
    406. case BRUSH_STYLE_VERTICAL:
    407. g_brushStyle = HS_VERTICAL; break;
    408. case BRUSH_STYLE_FDIAGONAL:
    409. g_brushStyle = HS_FDIAGONAL; break;
    410. case BRUSH_STYLE_BDIAGONAL:
    411. g_brushStyle = HS_BDIAGONAL; break;
    412. case BRUSH_STYLE_CROSS:
    413. g_brushStyle = HS_CROSS; break;
    414. case BRUSH_STYLE_DIAGCROSS:
    415. g_brushStyle = HS_DIAGCROSS; break;
    416. case BRUSH_STYLE_NULL:
    417. g_brushStyle = BRUSH_STYLE_SOLID;
    418. setBrushColor(EMPTY);
    419. return;
    420. default:
    421. break;
    422. }
    423. updateBrush();
    424. }
    425. void setTextColor(ACL_Color color)
    426. {
    427. ACL_ASSERT_BEGIN_PAINT;
    428. ACL_ASSERT(color!=EMPTY,"text color can not be EMPTY");
    429. g_textColor = color;
    430. SetTextColor(g_hmemdc,color);
    431. }
    432. void setTextBkColor(ACL_Color color)
    433. {
    434. ACL_ASSERT_BEGIN_PAINT;
    435. g_textBkColor = color;
    436. if(color == EMPTY)
    437. SetBkMode(g_hmemdc,TRANSPARENT);
    438. else
    439. {
    440. SetBkMode(g_hmemdc,OPAQUE);
    441. SetBkColor(g_hmemdc,color);
    442. }
    443. }
    444. void setTextSize(int size)
    445. {
    446. ACL_ASSERT_BEGIN_PAINT;
    447. g_textSize = size;
    448. updateFont();
    449. }
    450. void setTextFont(const char *pfn)
    451. {
    452. size_t len;
    453. ACL_ASSERT_BEGIN_PAINT;
    454. len = strlen(pfn);
    455. strcpy(g_fontName,pfn);
    456. updateFont();
    457. }
    458. void paintText(int x, int y, const char *textstring)
    459. {
    460. ACL_ASSERT_BEGIN_PAINT;
    461. TextOutA(g_hmemdc, x, y, textstring, strlen(textstring));
    462. }
    463. void putPixel(int x, int y, ACL_Color color)
    464. {
    465. ACL_ASSERT_BEGIN_PAINT;
    466. SetPixel(g_hmemdc, x, y, color);
    467. }
    468. ACL_Color getPixel(int x, int y)
    469. {
    470. ACL_ASSERT_BEGIN_PAINT;
    471. return GetPixel(g_hmemdc, x, y);
    472. }
    473. int getWidth(void)
    474. {
    475. RECT rect;
    476. GetClientRect(g_hWnd, &rect);
    477. return rect.right;
    478. }
    479. int getHeight(void)
    480. {
    481. RECT rect;
    482. GetClientRect(g_hWnd, &rect);
    483. return rect.bottom;
    484. }
    485. int getX(void)
    486. {
    487. POINT point;
    488. ACL_ASSERT_BEGIN_PAINT;
    489. GetCurrentPositionEx(g_hmemdc, &point);
    490. return (int) point.x;
    491. }
    492. int getY(void)
    493. {
    494. POINT point;
    495. ACL_ASSERT_BEGIN_PAINT;
    496. GetCurrentPositionEx(g_hmemdc, &point);
    497. return (int) point.y;
    498. }
    499. void moveTo(int x, int y)
    500. {
    501. ACL_ASSERT_BEGIN_PAINT;
    502. MoveToEx(g_hmemdc, x, y,NULL);
    503. }
    504. void moveRel(int dx, int dy)
    505. {
    506. POINT point;
    507. ACL_ASSERT_BEGIN_PAINT;
    508. GetCurrentPositionEx(g_hmemdc, &point);
    509. MoveToEx(g_hmemdc, (int) point.x + dx, (int) point.y + dy,NULL);
    510. }
    511. // Lines and Curves
    512. void arc(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4)
    513. {
    514. ACL_ASSERT_BEGIN_PAINT;
    515. Arc(g_hmemdc,x1,y1,x2,y2,x3,y3,x4,y4);
    516. }
    517. void line(int x0, int y0, int x1, int y1)
    518. {
    519. POINT point;
    520. ACL_ASSERT_BEGIN_PAINT;
    521. GetCurrentPositionEx(g_hmemdc, &point);
    522. MoveToEx(g_hmemdc, x0, y0, NULL);
    523. LineTo(g_hmemdc, x1, y1);
    524. MoveToEx(g_hmemdc,point.x,point.y,NULL);
    525. }
    526. void lineTo(int x, int y)
    527. {
    528. ACL_ASSERT_BEGIN_PAINT;
    529. LineTo(g_hmemdc, x, y);
    530. }
    531. void lineRel(int dx, int dy)
    532. {
    533. POINT point;
    534. ACL_ASSERT_BEGIN_PAINT;
    535. GetCurrentPositionEx(g_hmemdc, &point);
    536. LineTo(g_hmemdc, (int) point.x + dx, (int) point.y + dy);
    537. }
    538. void polyBezier(const POINT *lppt,int cPoints)
    539. {
    540. PolyBezier(g_hmemdc,lppt,cPoints);
    541. }
    542. void polyLine(const POINT *lppt, int cPoints)
    543. {
    544. Polyline(g_hmemdc,lppt,cPoints);
    545. }
    546. // Filled Shapes
    547. void chrod(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
    548. {
    549. ACL_ASSERT_BEGIN_PAINT;
    550. Chord(g_hmemdc,x1, y1, x2, y2, x3, y3, x4, y4);
    551. }
    552. void ellipse(int left,int top,int right, int bottom)
    553. {
    554. ACL_ASSERT_BEGIN_PAINT;
    555. Ellipse(g_hmemdc,left,top,right,bottom);
    556. }
    557. void pie(int left, int top, int right, int bottom, int xr1, int yr1, int xr2, int yr2)
    558. {
    559. ACL_ASSERT_BEGIN_PAINT;
    560. Pie(g_hmemdc,left,top,right,bottom,xr1,yr1,xr2,yr2);
    561. }
    562. void polygon(const POINT *apt,int cpt)
    563. {
    564. ACL_ASSERT_BEGIN_PAINT;
    565. Polygon(g_hmemdc,apt,cpt);
    566. }
    567. void rectangle(int left,int top,int right,int bottom)
    568. {
    569. ACL_ASSERT_BEGIN_PAINT;
    570. Rectangle(g_hmemdc,left,top,right,bottom);
    571. }
    572. void roundrect(int left,int top,int right,int bottom,int width,int height)
    573. {
    574. ACL_ASSERT_BEGIN_PAINT;
    575. RoundRect(g_hmemdc,left,top,right,bottom,width,height);
    576. }
    577. void polyline(POINT *apt,int cpt)
    578. {
    579. ACL_ASSERT_BEGIN_PAINT;
    580. Polyline(g_hmemdc,apt,cpt);
    581. }
    582. void putImage(ACL_Image *pImage, int x, int y)
    583. {
    584. HDC hbitmapdc;
    585. ACL_ASSERT_BEGIN_PAINT;
    586. hbitmapdc = CreateCompatibleDC(g_hmemdc);
    587. SelectObject(hbitmapdc, pImage->hbitmap);
    588. BitBlt(g_hmemdc, x, y, pImage->width, pImage->height, hbitmapdc,0,0,SRCCOPY);
    589. DeleteDC(hbitmapdc);
    590. }
    591. void putImageScale(ACL_Image *pImage,int x,int y,int width,int height)
    592. {
    593. HDC hbitmapdc;
    594. ACL_ASSERT_BEGIN_PAINT;
    595. hbitmapdc = CreateCompatibleDC(g_hmemdc);
    596. SelectObject(hbitmapdc, pImage->hbitmap);
    597. if(width == -1)width = pImage->width;
    598. if(height == -1)height = pImage->height;
    599. SetStretchBltMode(g_hmemdc,COLORONCOLOR);
    600. StretchBlt( g_hmemdc,x,y,width,height,hbitmapdc,0,0,pImage->width,pImage->height,SRCCOPY);
    601. DeleteDC(hbitmapdc);
    602. }
    603. void putImageTransparent(ACL_Image *pImage,int x,int y,int width,int height, ACL_Color bkColor)
    604. {
    605. HDC hbitmapdc;
    606. ACL_ASSERT_BEGIN_PAINT;
    607. hbitmapdc = CreateCompatibleDC(g_hmemdc);
    608. SelectObject(hbitmapdc, pImage->hbitmap);
    609. if(width == -1)width = pImage->width;
    610. if(height == -1)height = pImage->height;
    611. //SetStretchBltMode(g_hmemdc,COLORONCOLOR);
    612. TransparentBlt(g_hmemdc,x,y,width,height,hbitmapdc,0,0,pImage->width,pImage->height,bkColor);
    613. DeleteDC(hbitmapdc);
    614. }
    615. void loadImage(const char *image, ACL_Image *mapbuf)
    616. {
    617. HDC hmapdc;
    618. IPicture *ipicture;
    619. IStream *istream;
    620. DWORD filesize = 0, bytes;
    621. OLE_XSIZE_HIMETRIC width;
    622. OLE_YSIZE_HIMETRIC height;
    623. HANDLE file = NULL;
    624. HGLOBAL global = NULL;
    625. LPVOID data = NULL;
    626. ACL_ASSERT_HWND;
    627. file = CreateFileA(image, GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
    628. if(file == INVALID_HANDLE_VALUE)
    629. acl_error("Fail to load image, File not exist");
    630. filesize = GetFileSize(file, NULL);
    631. global = GlobalAlloc(GMEM_MOVEABLE, filesize);
    632. data = GlobalLock(global);
    633. ReadFile(file, data, filesize, &bytes, NULL);
    634. GlobalUnlock(global);
    635. CreateStreamOnHGlobal(global, TRUE, &istream);
    636. OleLoadPicture(istream, filesize, TRUE, &IID_IPicture, (LPVOID*)&ipicture);
    637. ipicture->lpVtbl->get_Width(ipicture, &width);
    638. ipicture->lpVtbl->get_Height(ipicture, &height);
    639. mapbuf->width = (int)(width / 26.45833333333);
    640. mapbuf->height = (int)(height / 26.45833333333);
    641. hmapdc = CreateCompatibleDC(GetDC(g_hWnd));
    642. if (mapbuf->hbitmap != NULL)
    643. DeleteObject(mapbuf->hbitmap);
    644. mapbuf->hbitmap = CreateCompatibleBitmap(GetDC(g_hWnd), mapbuf->width, mapbuf->height);
    645. SelectObject(hmapdc, mapbuf->hbitmap);
    646. ipicture->lpVtbl->Render(ipicture, hmapdc, 0, 0, mapbuf->width, mapbuf->height, 0, height, width, -height, NULL);
    647. ipicture->lpVtbl->Release(ipicture);
    648. istream->lpVtbl->Release(istream);
    649. DeleteDC(hmapdc);
    650. GlobalFree(global);
    651. CloseHandle(file);
    652. }
    653. void freeImage(ACL_Image *mapbuf)
    654. {
    655. if(mapbuf->hbitmap) return;
    656. DeleteObject(mapbuf->hbitmap);
    657. mapbuf->hbitmap = NULL;
    658. }
    659. void registerKeyboardEvent(KeyboardEventCallback callback)
    660. {
    661. g_keyboard = callback;
    662. }
    663. void registerCharEvent(CharEventCallback callback)
    664. {
    665. g_char = callback;
    666. }
    667. void registerMouseEvent(MouseEventCallback callback)
    668. {
    669. g_mouse = callback;
    670. }
    671. void registerTimerEvent(TimerEventCallback callback)
    672. {
    673. g_timer = callback;
    674. }
    675. void startTimer(int id,int timeinterval)
    676. {
    677. SetTimer(g_hWnd, id, timeinterval, NULL);
    678. }
    679. void cancelTimer(int id)
    680. {
    681. KillTimer(g_hWnd, id);
    682. }
    683. void loadSound(const char *fileName,ACL_Sound *pSound)
    684. {
    685. char *cmdStr;
    686. int len = strlen(fileName)*sizeof(char);
    687. len +=64;
    688. cmdStr = (char*)malloc(len);
    689. sprintf(cmdStr,"open \"%s\" type mpegvideo alias S%d",fileName,g_soundID);
    690. *pSound = g_soundID;
    691. ++g_soundID;
    692. mciSendStringA(cmdStr,NULL,0,NULL);
    693. free(cmdStr);
    694. }
    695. void playSound(int sid,int repeat)
    696. {
    697. char cmdStr[32];
    698. stopSound(sid);
    699. if(repeat)
    700. sprintf(cmdStr,"play S%d from 0 repeat",sid);
    701. else
    702. sprintf(cmdStr,"play S%d from 0",sid);
    703. mciSendStringA(cmdStr,NULL,0,NULL);
    704. }
    705. void stopSound(int sid)
    706. {
    707. char cmdStr[32];
    708. sprintf(cmdStr,"stop S%d",sid);
    709. mciSendStringA(cmdStr,NULL,0,NULL);
    710. }
    711. void setCaretSize(int w,int h)
    712. {
    713. DestroyCaret();
    714. CreateCaret(g_hWnd,0,w,h);
    715. SetCaretPos(g_caretX,g_caretY);
    716. }
    717. void setCaretPos(int x,int y)
    718. {
    719. g_caretX = x;
    720. g_caretY = y;
    721. SetCaretPos(g_caretX,g_caretY);
    722. }
    723. void showCaret()
    724. {
    725. ShowCaret(g_hWnd);
    726. }
    727. void hideCaret()
    728. {
    729. HideCaret(g_hWnd);
    730. }