PAINT.C
上传用户:cncajx
上传日期:2007-01-03
资源大小:190k
文件大小:31k
源码类别:

GDI/图象编程

开发平台:

Visual C++

  1.   1 /****************************************************************/
  2.   2 /*         Paint   ---  My Paint                                */
  3.   3 /****************************************************************/
  4.   4 
  5.   5 #include <windows.h>
  6.   6 #include <math.h>
  7.   7 #include "Paint.h"
  8.   8 
  9.   9 int  PASCAL  WinMain(HANDLE, HANDLE, LPSTR, int);
  10.  10 long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
  11.  11 long FAR PASCAL ChooseCtrlProc(HWND, unsigned, WORD, LONG);
  12.  12 long FAR PASCAL LineWSCtrlProc(HWND, unsigned, WORD, LONG);
  13.  13 BOOL FAR PASCAL PenDlgProc(HWND, unsigned, WORD, LONG);
  14.  14 BOOL FAR PASCAL BrushDlgProc(HWND, unsigned, WORD, LONG);
  15.  15 
  16.  16 void BackUpGraph(HDC, HMENU, int, int, int, int, int, int);
  17.  17 
  18.  18 void DrawGraph(HDC, HMENU, BOOL);
  19.  19 void DrawPencil(HDC, HMENU);
  20.  20 void DrawLine(HDC, HMENU, BOOL);
  21.  21 void DrawRect(HDC, HMENU, BOOL);
  22.  22 void DrawEllip(HDC, HMENU, BOOL);
  23.  23 void DrawCircle(HDC, HMENU, BOOL);
  24.  24 void DrawRoundRect(HDC, HMENU, BOOL);
  25.  25 void Erase(HDC, HMENU, BOOL);
  26.  26 
  27.  27 /****  defined in paint_fn.c  ****/
  28.  28 void MakeFontMenu(HWND);
  29.  29 void MakeStyleMenu(HMENU);
  30.  30 void DeleteStyleMenu();
  31.  31 void BeginWrite(HWND, int, int);
  32.  32 void EndWrite(HWND);
  33.  33 
  34.  34 /****  defined in paint_pr.c  ****/
  35.  35 void PrintGraph(HWND, int, int);
  36.  36 
  37.  37 /****  defined in paint_bk.c  ****/
  38.  38 void CancelBound(HDC, HMENU);
  39.  39 void RecoverBlock();
  40.  40 void Copy(HWND);
  41.  41 void Paste(HWND);
  42.  42 void Cut(HWND);
  43.  43 
  44.  44 /****  defined in paint_fi.c  ****/
  45.  45 void NewFile(HWND, BOOL);
  46.  46 void FileOpen(HWND);
  47.  47 void FileSaveAs(HWND);
  48.  48 void FileSave(HWND);
  49.  49 
  50.  50 FARPROC lpPenDlgProc;
  51.  51 FARPROC lpBrushDlgProc;
  52.  52 
  53.  53 HANDLE  hInst;
  54.  54 
  55.  55 int     OX=0, OY=0;
  56.  56 int     CX, CY;
  57.  57 int     MemX=960, MemY=900;
  58.  58 
  59.  59 int     nLogPixSx;
  60.  60 int     nLogPixSy;
  61.  61 
  62.  62 int     ToolID  = IDM_PENCIL;
  63.  63 
  64.  64 int     nPenColor = 1;
  65.  65 int     nPenStyle = PS_SOLID;
  66.  66 int     nPenWidth = 1;
  67.  67 
  68.  68 int     nBrushColor = 1;
  69.  69 int     nHatch      = -1;
  70.  70 
  71.  71 POINT   OrgPoint;
  72.  72 POINT   PrePoint;
  73.  73 POINT   CurPoint;
  74.  74 
  75.  75 BOOL    CanUndo;
  76.  76 HBITMAP hBitmap;
  77.  77 HDC     hMemDC;
  78.  78 
  79.  79 /****  declared in paint_dg.c  ****/
  80.  80 typedef struct tagCOLORSTRUCT {
  81.  81    int  cR;
  82.  82    int  cG;
  83.  83    int  cB;
  84.  84 } COLORSTRUCT;
  85.  85 
  86.  86 #define MKCOLOR(A) (RGB(A.cR, A.cG, A.cB))
  87.  87 
  88.  88 extern COLORSTRUCT crDefColor[28];
  89.  89 extern COLORSTRUCT crPCurColor[28];
  90.  90 extern COLORSTRUCT crBCurColor[28];
  91.  91 
  92.  92 
  93.  93 /****  declared in paint_fn.c  ****/
  94.  94 extern BOOL bNormal;
  95.  95 extern BOOL bTextWorking;
  96.  96 extern int  CharX, CharY;
  97.  97 extern int  CharPosX, CharPosY;
  98.  98 extern BOOL bCaret;
  99.  99 
  100. 100 /****  declared in paint_bk.c  ****/
  101. 101 extern BOOL bBounded;
  102. 102 
  103. 103 
  104. 104 /****************************************************************/
  105. 105 /*                      WinMain()                               */
  106. 106 /****************************************************************/
  107. 107 
  108. 108 int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  109. 109                    LPSTR lpszCmdLine, int nCmdShow)
  110. 110 {
  111. 111    WNDCLASS wclass;
  112. 112    MSG      msg;
  113. 113    HWND     hWnd;
  114. 114    char     szName[] = "Paint";
  115. 115 
  116. 116    if (!hPrevInstance)
  117. 117     {
  118. 118         wclass.style         = CS_HREDRAW | CS_VREDRAW;
  119. 119         wclass.lpfnWndProc   = MainWndProc;
  120. 120         wclass.cbClsExtra    = 0;
  121. 121         wclass.cbWndExtra    = 0;
  122. 122         wclass.hInstance     = hInstance;
  123. 123         wclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  124. 124         wclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  125. 125         wclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  126. 126         wclass.lpszMenuName  = szName;
  127. 127         wclass.lpszClassName = szName;
  128. 128 
  129. 129         if (!RegisterClass (&wclass))
  130. 130            return (FALSE);
  131. 131 
  132. 132         wclass.style         = CS_HREDRAW | CS_VREDRAW;
  133. 133         wclass.lpfnWndProc   = ChooseCtrlProc;
  134. 134         wclass.cbClsExtra    = 0;
  135. 135         wclass.cbWndExtra    = 0;
  136. 136         wclass.hInstance     = hInstance;
  137. 137         wclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  138. 138         wclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  139. 139         wclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  140. 140         wclass.lpszMenuName  = NULL;
  141. 141         wclass.lpszClassName = "Choose";
  142. 142 
  143. 143         if (!RegisterClass (&wclass))
  144. 144            return (FALSE);
  145. 145 
  146. 146         wclass.style         = CS_HREDRAW | CS_VREDRAW;
  147. 147         wclass.lpfnWndProc   = LineWSCtrlProc;
  148. 148         wclass.cbClsExtra    = 0;
  149. 149         wclass.cbWndExtra    = 0;
  150. 150         wclass.hInstance     = hInstance;
  151. 151         wclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  152. 152         wclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  153. 153         wclass.hbrBackground = COLOR_WINDOW + 1;
  154. 154         wclass.lpszMenuName  = NULL;
  155. 155         wclass.lpszClassName = "LineWS";
  156. 156 
  157. 157         if (!RegisterClass (&wclass))
  158. 158            return (FALSE);
  159. 159     }
  160. 160 
  161. 161     hWnd = CreateWindow(
  162. 162                 szName,
  163. 163                 "My Paint" ,
  164. 164                 WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
  165. 165                 CW_USEDEFAULT,
  166. 166                 CW_USEDEFAULT,
  167. 167                 CW_USEDEFAULT,
  168. 168                 CW_USEDEFAULT,
  169. 169                 NULL,
  170. 170                 NULL,
  171. 171                 hInstance,
  172. 172                 NULL );
  173. 173 
  174. 174     if (!hWnd)
  175. 175         return (FALSE);
  176. 176 
  177. 177     ShowWindow(hWnd, nCmdShow);
  178. 178     UpdateWindow(hWnd);
  179. 179 
  180. 180     while (GetMessage(&msg, NULL, NULL,NULL))
  181. 181        {
  182. 182            TranslateMessage(&msg);
  183. 183            DispatchMessage(&msg);
  184. 184        }
  185. 185     return (msg.wParam);
  186. 186 }
  187. 187 
  188. 188 
  189. 189 /****************************************************************/
  190. 190 /*                      MainWndProc()                           */
  191. 191 /****************************************************************/
  192. 192 
  193. 193 long FAR PASCAL MainWndProc(HWND hWnd, unsigned message,
  194. 194                             WORD wParam, LONG lParam)
  195. 195 {
  196. 196    HDC           hDC;
  197. 197    HMENU         hMenu;
  198. 198    PAINTSTRUCT   ps;
  199. 199    int           Temp;
  200. 200    static BOOL   bLBDown;
  201. 201 
  202. 202    switch (message)
  203. 203     {
  204. 204       case WM_CREATE :
  205. 205                 hInst =
  206. 206                     ((LPCREATESTRUCT) lParam)->hInstance;
  207. 207 
  208. 208             /****   Process normal menu          ****/
  209. 209 
  210. 210                 hMenu = GetMenu(hWnd);
  211. 211                 CheckMenuItem(hMenu, IDM_PENCIL,
  212. 212                               MF_CHECKED);
  213. 213                 EnableMenuItem(hMenu, IDM_UNDO, MF_GRAYED);
  214. 214                 EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED);
  215. 215                 EnableMenuItem(hMenu, IDM_PASTE, MF_GRAYED);
  216. 216                 EnableMenuItem(hMenu, IDM_CUT, MF_GRAYED);
  217. 217 
  218. 218             /****   Make copy of 28 color value  ****/
  219. 219 
  220. 220                 memcpy(crPCurColor, crDefColor,
  221. 221                                 sizeof(crDefColor));
  222. 222                 memcpy(crBCurColor, crDefColor,
  223. 223                                 sizeof(crDefColor));
  224. 224 
  225. 225             /*** Create bitmap & MemDC for backup ***/
  226. 226 
  227. 227                 hDC = GetDC(hWnd);
  228. 228                 hMemDC = CreateCompatibleDC(hDC);
  229. 229                 hBitmap = CreateCompatibleBitmap(hDC,
  230. 230                                                 MemX, MemY);
  231. 231                 SelectObject(hMemDC, hBitmap);
  232. 232 
  233. 233                 NewFile(hWnd, 1);
  234. 234 
  235. 235             /****   Create Font menu         ****/
  236. 236 
  237. 237                 nLogPixSx = GetDeviceCaps(hDC, LOGPIXELSX);
  238. 238                 nLogPixSy = GetDeviceCaps(hDC, LOGPIXELSY);
  239. 239                 ReleaseDC(hWnd, hDC);
  240. 240 
  241. 241                 MakeStyleMenu(hMenu);
  242. 242                 MakeFontMenu(hWnd);
  243. 243                 bNormal = FALSE;
  244. 244                 SendMessage(hWnd, WM_COMMAND, IDM_NORM, 0L);
  245. 245 
  246. 246                 return (0);
  247. 247 
  248. 248       case WM_COMMAND :
  249. 249                 hMenu = GetMenu(hWnd);
  250. 250 
  251. 251                 if (wParam>=IDM_NORM &&
  252. 252                     wParam<=IDM_SIZE+MAXFACES+MAXSIZES)
  253. 253                   ChooseFontMenu(hWnd, wParam);
  254. 254                 else
  255. 255                 switch (wParam)
  256. 256                   {
  257. 257                     case IDM_PENCIL     :
  258. 258                     case IDM_LINE       :
  259. 259 
  260. 260                     case IDM_BLOCK      :
  261. 261                     case IDM_TEXT       :
  262. 262                     case IDM_ERASE      :
  263. 263 
  264. 264                     case IDM_RECT       :
  265. 265                     case IDM_ELLIP      :
  266. 266                     case IDM_CIRCLE     :
  267. 267                     case IDM_ROUNDRECT  :
  268. 268 
  269. 269                     case IDM_RECT_F     :
  270. 270                     case IDM_ELLIP_F    :
  271. 271                     case IDM_CIRCLE_F   :
  272. 272                     case IDM_ROUNDRECT_F:
  273. 273 
  274. 274                          if (ToolID == wParam)
  275. 275                             return (0);
  276. 276 
  277. 277                          if (ToolID == IDM_TEXT)
  278. 278                            EndWrite(hWnd);
  279. 279 
  280. 280                          hDC = GetDC(hWnd);
  281. 281                          BackUpGraph(hDC, hMenu,
  282. 282                                      OX, OY, CX, CY,
  283. 283                                      0, 0);
  284. 284                          ReleaseDC(hWnd, hDC);
  285. 285 
  286. 286                          CheckMenuItem(hMenu, ToolID,
  287. 287                                         MF_UNCHECKED);
  288. 288                          ToolID = wParam;
  289. 289                          CheckMenuItem(hMenu, ToolID,
  290. 290                                         MF_CHECKED);
  291. 291                          break;
  292. 292 
  293. 293                     case IDM_CHOOSEPEN :
  294. 294 
  295. 295                          lpPenDlgProc = MakeProcInstance(
  296. 296                                (FARPROC) PenDlgProc, hInst);
  297. 297 
  298. 298                          DialogBox(hInst, "PENDLG", hWnd,
  299. 299                                    lpPenDlgProc);
  300. 300 
  301. 301                          FreeProcInstance(lpPenDlgProc);
  302. 302                          break;
  303. 303 
  304. 304                     case IDM_CHOOSEBRUSH :
  305. 305 
  306. 306                          lpBrushDlgProc = MakeProcInstance(
  307. 307                                (FARPROC) BrushDlgProc, hInst);
  308. 308 
  309. 309                          DialogBox(hInst, "BRUSHDLG", hWnd,
  310. 310                                    lpBrushDlgProc);
  311. 311 
  312. 312                          FreeProcInstance(lpBrushDlgProc);
  313. 313                          break;
  314. 314 
  315. 315                     case IDM_NEW :
  316. 316                          if (bTextWorking)
  317. 317                            EndWrite(hWnd);
  318. 318                          NewFile(hWnd, 0);
  319. 319                          InvalidateRect(hWnd, NULL, FALSE);
  320. 320                          break;
  321. 321 
  322. 322                     case IDM_OPEN :
  323. 323                          if (bTextWorking)
  324. 324                            EndWrite(hWnd);
  325. 325                          FileOpen(hWnd);
  326. 326                          break;
  327. 327 
  328. 328                     case IDM_SAVE :
  329. 329                          hDC = GetDC(hWnd);
  330. 330                          BackUpGraph(hDC, hMenu,
  331. 331                                      OX, OY, CX, CY,
  332. 332                                      0, 0);
  333. 333                          ReleaseDC(hWnd, hDC);
  334. 334 
  335. 335                          FileSave(hWnd);
  336. 336                          break;
  337. 337 
  338. 338                     case IDM_SAVEAS :
  339. 339                          hDC = GetDC(hWnd);
  340. 340                          BackUpGraph(hDC, hMenu,
  341. 341                                      OX, OY, CX, CY,
  342. 342                                      0, 0);
  343. 343                          ReleaseDC(hWnd, hDC);
  344. 344 
  345. 345                          FileSaveAs(hWnd);
  346. 346                          break;
  347. 347 
  348. 348                     case IDM_PRINT :
  349. 349                          if (bTextWorking)
  350. 350                            EndWrite(hWnd);
  351. 351 
  352. 352                          hDC = GetDC(hWnd);
  353. 353                          BackUpGraph(hDC, hMenu,
  354. 354                                      OX, OY, CX, CY,
  355. 355                                      0, 0);
  356. 356                          ReleaseDC(hWnd, hDC);
  357. 357 
  358. 358                          PrintGraph(hWnd, MemX, MemY);
  359. 359                          break;
  360. 360 
  361. 361                     case IDM_QUIT :
  362. 362                          SendMessage(hWnd, WM_CLOSE, 0, 0);
  363. 363                          break;
  364. 364 
  365. 365                     case IDM_UNDO :
  366. 366                          if (ToolID == IDM_BLOCK)
  367. 367                            {
  368. 368                              hDC = GetDC(hWnd);
  369. 369                              RecoverBlock();
  370. 370                              CancelBound(hDC, hMenu);
  371. 371                              ReleaseDC(hWnd, hDC);
  372. 372                            }
  373. 373                          if (bTextWorking)
  374. 374                            EndWrite(hWnd);
  375. 375 
  376. 376                          InvalidateRect(hWnd, NULL, FALSE);
  377. 377                          EnableMenuItem(hMenu, IDM_UNDO,
  378. 378                                         MF_GRAYED);
  379. 379                          CanUndo = FALSE;
  380. 380                          break;
  381. 381 
  382. 382                     case IDM_COPY :
  383. 383                          if (ToolID == IDM_BLOCK)
  384. 384                            Copy(hWnd);
  385. 385                          break;
  386. 386 
  387. 387                     case IDM_PASTE :
  388. 388                          Paste(hWnd);
  389. 389                          break;
  390. 390 
  391. 391                     case IDM_CUT :
  392. 392                          if (ToolID == IDM_BLOCK)
  393. 393                            Cut(hWnd);
  394. 394                          break;
  395. 395                   }
  396. 396                 return (0);
  397. 397 
  398. 398       case WM_INITMENUPOPUP :
  399. 399                 if (LOWORD(lParam)==1 &&
  400. 400                     HIWORD(lParam)==0)
  401. 401                   {
  402. 402                      if (IsClipboardFormatAvailable(
  403. 403                                               CF_BITMAP))
  404. 404                         EnableMenuItem(wParam, IDM_PASTE,
  405. 405                                        MF_ENABLED);
  406. 406                      else
  407. 407                         EnableMenuItem(wParam, IDM_PASTE,
  408. 408                                        MF_GRAYED);
  409. 409                   }
  410. 410 
  411. 411                 return (0);
  412. 412 
  413. 413       case WM_LBUTTONDOWN :
  414. 414                 if (ToolID == IDM_TEXT)
  415. 415                   {
  416. 416                     BeginWrite(hWnd,
  417. 417                                LOWORD(lParam),
  418. 418                                HIWORD(lParam));
  419. 419                     return (0);
  420. 420                   }
  421. 421 
  422. 422                 if (bLBDown == TRUE)
  423. 423                   return (0);
  424. 424 
  425. 425                 SetCapture(hWnd);
  426. 426                 bLBDown = TRUE;
  427. 427 
  428. 428                 OrgPoint = MAKEPOINT(lParam);
  429. 429                 CurPoint = PrePoint = OrgPoint;
  430. 430 
  431. 431                 hDC = GetDC(hWnd);
  432. 432                 DrawGraph(hDC, GetMenu(hWnd), FALSE);
  433. 433                 ReleaseDC(hWnd, hDC);
  434. 434 
  435. 435                 return (0);
  436. 436 
  437. 437       case WM_LBUTTONUP :
  438. 438                 if (bLBDown == FALSE)
  439. 439                   return (0);
  440. 440                 bLBDown = FALSE;
  441. 441                 ReleaseCapture();
  442. 442 
  443. 443                 hDC = GetDC(hWnd);
  444. 444                 DrawGraph(hDC, GetMenu(hWnd), TRUE);
  445. 445                 ReleaseDC(hWnd, hDC);
  446. 446 
  447. 447                 return (0);
  448. 448 
  449. 449       case WM_MOUSEMOVE :
  450. 450                 if (bLBDown)
  451. 451                   {
  452. 452                     PrePoint = CurPoint;
  453. 453                     CurPoint = MAKEPOINT(lParam);
  454. 454 
  455. 455                     hDC = GetDC(hWnd);
  456. 456                     DrawGraph(hDC, GetMenu(hWnd), FALSE);
  457. 457                     ReleaseDC(hWnd, hDC);
  458. 458                   }
  459. 459                 return (0);
  460. 460 
  461. 461       case WM_CHAR :
  462. 462                 if (bTextWorking)
  463. 463                   ProcessChar(hWnd, wParam);
  464. 464                 return (0);
  465. 465 
  466. 466       case WM_SIZE :
  467. 467                 CX = LOWORD(lParam);
  468. 468                 CY = HIWORD(lParam);
  469. 469                 SetScrollRange(hWnd, SB_HORZ,
  470. 470                                0, MemX-CX, TRUE);
  471. 471                 SetScrollRange(hWnd, SB_VERT,
  472. 472                                0, MemY-CY, TRUE);
  473. 473                 OX = min(OX, MemX-CX);
  474. 474                 OY = min(OY, MemY-CY);
  475. 475                 SetScrollPos(hWnd, SB_HORZ, OX, TRUE);
  476. 476                 SetScrollPos(hWnd, SB_VERT, OY, TRUE);
  477. 477                 return (0);
  478. 478 
  479. 479       case WM_PAINT :
  480. 480                 hDC = BeginPaint(hWnd, &ps);
  481. 481 
  482. 482                 BitBlt(hDC,
  483. 483                        ps.rcPaint.left,
  484. 484                        ps.rcPaint.top,
  485. 485                        ps.rcPaint.right-ps.rcPaint.left,
  486. 486                        ps.rcPaint.bottom-ps.rcPaint.top,
  487. 487                        hMemDC,
  488. 488                        OX+ps.rcPaint.left,
  489. 489                        OY+ps.rcPaint.top,
  490. 490                        SRCCOPY);
  491. 491 
  492. 492                 EndPaint(hWnd, &ps);
  493. 493                 return (0);
  494. 494 
  495. 495       case WM_HSCROLL :
  496. 496                 switch (wParam)
  497. 497                   {
  498. 498                     case SB_TOP :
  499. 499                         Temp = 0;
  500. 500                         break;
  501. 501 
  502. 502                     case SB_BOTTOM :
  503. 503                         Temp = MemX - CX;
  504. 504                         break;
  505. 505 
  506. 506                     case SB_LINEUP :
  507. 507                         Temp = OX - 20;
  508. 508                         break;
  509. 509 
  510. 510                     case SB_PAGEUP :
  511. 511                         Temp = OX - CX;
  512. 512                         break;
  513. 513 
  514. 514                     case SB_LINEDOWN :
  515. 515                         Temp = OX + 20;
  516. 516                         break;
  517. 517 
  518. 518                     case SB_PAGEDOWN :
  519. 519                         Temp = OX + CX;
  520. 520                         break;
  521. 521 
  522. 522                     case SB_THUMBPOSITION :
  523. 523                         Temp = LOWORD(lParam);
  524. 524                         break;
  525. 525 
  526. 526                     default :
  527. 527                         return (NULL);
  528. 528                   }
  529. 529                 Temp = min(max(0, Temp), MemX-CX);
  530. 530                 if (Temp == OX) return (0);
  531. 531 
  532. 532                 OX = Temp;
  533. 533                 SetScrollPos(hWnd, SB_HORZ, OX, TRUE);
  534. 534                 InvalidateRect(hWnd, NULL, TRUE);
  535. 535 
  536. 536                 return (0);
  537. 537 
  538. 538       case WM_VSCROLL :
  539. 539                 switch (wParam)
  540. 540                   {
  541. 541                     case SB_TOP :
  542. 542                         Temp = 0;
  543. 543                         break;
  544. 544 
  545. 545                     case SB_BOTTOM :
  546. 546                         Temp = MemY - CY;
  547. 547                         break;
  548. 548 
  549. 549                     case SB_LINEUP :
  550. 550                         Temp = OY - 20;
  551. 551                         break;
  552. 552 
  553. 553                     case SB_PAGEUP :
  554. 554                         Temp = OY - CY;
  555. 555                         break;
  556. 556 
  557. 557                     case SB_LINEDOWN :
  558. 558                         Temp = OY + 20;
  559. 559                         break;
  560. 560 
  561. 561                     case SB_PAGEDOWN :
  562. 562                         Temp = OY + CY;
  563. 563                         break;
  564. 564 
  565. 565                     case SB_THUMBPOSITION :
  566. 566                         Temp = LOWORD(lParam);
  567. 567                         break;
  568. 568 
  569. 569                     default :
  570. 570                         return (NULL);
  571. 571                   }
  572. 572                 Temp = min(max(0, Temp), MemY-CY);
  573. 573                 if (Temp == OY) return (0);
  574. 574 
  575. 575                 OY = Temp;
  576. 576                 SetScrollPos(hWnd, SB_VERT, OY, TRUE);
  577. 577                 InvalidateRect(hWnd, NULL, TRUE);
  578. 578 
  579. 579                 return (0);
  580. 580 
  581. 581       case WM_SETFOCUS :
  582. 582                 if (bTextWorking)
  583. 583                   {
  584. 584                     CreateCaret(hWnd, NULL, 1, CharY);
  585. 585                     SetCaretPos(CharPosX, CharPosY);
  586. 586                     ShowCaret(hWnd);
  587. 587                     bCaret = TRUE;
  588. 588                   }
  589. 589                 return (0);
  590. 590 
  591. 591       case WM_KILLFOCUS :
  592. 592                 if (bTextWorking)
  593. 593                   {
  594. 594                     HideCaret(hWnd);
  595. 595                     DestroyCaret();
  596. 596                     bCaret = FALSE;
  597. 597                   }
  598. 598                 return (0);
  599. 599 
  600. 600       case WM_ACTIVATE :
  601. 601                 if (wParam != 0)
  602. 602                   break;
  603. 603                                 // fall through
  604. 604       case WM_SYSCOMMAND :
  605. 605 
  606. 606                 if (message==WM_ACTIVATE ||
  607. 607                     ((wParam & 0xfff0) != SC_MOUSEMENU &&
  608. 608                      (wParam & 0xfff0) != SC_KEYMENU))
  609. 609                   {
  610. 610                     if (bTextWorking)
  611. 611                       EndWrite(hWnd);
  612. 612 
  613. 613                     hMenu = GetMenu(hWnd);
  614. 614 
  615. 615                     hDC = GetDC(hWnd);
  616. 616                     BackUpGraph(hDC, hMenu,
  617. 617                                 OX, OY, CX, CY,
  618. 618                                 0, 0);
  619. 619                     ReleaseDC(hWnd, hDC);
  620. 620                   }
  621. 621                 break;
  622. 622 
  623. 623       case WM_CLOSE :
  624. 624                 if (bTextWorking)
  625. 625                   EndWrite(hWnd);
  626. 626 
  627. 627                 if (QuerySave(hWnd) == IDCANCEL)
  628. 628                   return (0);
  629. 629                 break;
  630. 630 
  631. 631       case WM_DESTROY :
  632. 632                 DeleteDC(hMemDC);
  633. 633                 DeleteObject(hBitmap);
  634. 634                 DeleteStyleMenu();
  635. 635                 PostQuitMessage(0);
  636. 636                 return (0);
  637. 637     }
  638. 638    return(DefWindowProc(hWnd, message, wParam, lParam));
  639. 639 }
  640. 640 
  641. 641 
  642. 642 
  643. 643 void BackUpGraph(HDC hDC, HMENU hMenu,
  644. 644                  int OX, int OY, int W, int H,
  645. 645                  int X, int Y)
  646. 646 {
  647. 647    if (ToolID==IDM_BLOCK)
  648. 648      CancelBound(hDC, hMenu);
  649. 649 
  650. 650    if (CanUndo)
  651. 651      {
  652. 652        BitBlt(hMemDC, OX, OY, W, H,
  653. 653               hDC, X, Y, SRCCOPY);
  654. 654 
  655. 655        EnableMenuItem(hMenu, IDM_UNDO, MF_GRAYED);
  656. 656        CanUndo = FALSE;
  657. 657      }
  658. 658 }
  659. 659 
  660. 660 
  661. 661 
  662. 662 HBRUSH MyCreateBrush(int nHatchStyle, COLORREF crColor)
  663. 663 {
  664. 664    HBRUSH hBrush;
  665. 665 
  666. 666    if (nHatchStyle == -1)
  667. 667      hBrush = CreateSolidBrush(crColor);
  668. 668    else
  669. 669      hBrush = CreateHatchBrush(nHatchStyle, crColor);
  670. 670 
  671. 671    return (hBrush);
  672. 672 }
  673. 673 
  674. 674 
  675. 675 
  676. 676 void DrawGraph(HDC hDC, HMENU hMenu, BOOL bSure)
  677. 677 {
  678. 678    HPEN   hPen, hPrePen;
  679. 679    HBRUSH hBrush, hPreBrush;
  680. 680 
  681. 681    if (ToolID==IDM_PENCIL || bSure)
  682. 682      {
  683. 683        hPen   = CreatePen(nPenStyle, nPenWidth,
  684. 684                         MKCOLOR(crPCurColor[nPenColor]));
  685. 685        hPrePen   = SelectObject(hDC, hPen);
  686. 686 
  687. 687        if (ToolID==IDM_RECT_F   || ToolID==IDM_ELLIP_F ||
  688. 688            ToolID==IDM_CIRCLE_F || ToolID==IDM_ROUNDRECT_F)
  689. 689          {
  690. 690            hBrush = MyCreateBrush(nHatch,
  691. 691                         MKCOLOR(crBCurColor[nBrushColor]));
  692. 692            hPreBrush  = SelectObject(hDC, hBrush);
  693. 693          }
  694. 694        else
  695. 695          {
  696. 696            hBrush = GetStockObject(NULL_BRUSH);
  697. 697            hPreBrush  = SelectObject(hDC, hBrush);
  698. 698          }
  699. 699      }
  700. 700    else
  701. 701      SelectObject(hDC, GetStockObject(NULL_BRUSH));
  702. 702 
  703. 703    switch (ToolID)
  704. 704      {
  705. 705        case IDM_PENCIL :
  706. 706               DrawPencil(hDC, hMenu);
  707. 707               break;
  708. 708 
  709. 709        case IDM_LINE :
  710. 710               DrawLine(hDC, hMenu, bSure);
  711. 711               break;
  712. 712 
  713. 713        case IDM_BLOCK :
  714. 714               BoundBlock(hDC, hMenu, bSure);
  715. 715               break;
  716. 716 
  717. 717        case IDM_ERASE :
  718. 718               Erase(hDC, hMenu, bSure);
  719. 719               break;
  720. 720 
  721. 721        case IDM_RECT_F :
  722. 722        case IDM_RECT   :
  723. 723               DrawRect(hDC, hMenu, bSure);
  724. 724               break;
  725. 725 
  726. 726        case IDM_ELLIP_F :
  727. 727        case IDM_ELLIP   :
  728. 728               DrawEllip(hDC, hMenu, bSure);
  729. 729               break;
  730. 730 
  731. 731        case IDM_CIRCLE_F :
  732. 732        case IDM_CIRCLE   :
  733. 733               DrawCircle(hDC, hMenu, bSure);
  734. 734               break;
  735. 735 
  736. 736        case IDM_ROUNDRECT_F :
  737. 737        case IDM_ROUNDRECT   :
  738. 738               DrawRoundRect(hDC, hMenu, bSure);
  739. 739               break;
  740. 740      }
  741. 741 
  742. 742    if (ToolID==IDM_PENCIL || bSure)
  743. 743      {
  744. 744        SelectObject(hDC, hPrePen);
  745. 745        DeleteObject(hPen);
  746. 746 
  747. 747        if (ToolID==IDM_RECT_F   || ToolID==IDM_ELLIP_F ||
  748. 748            ToolID==IDM_CIRCLE_F || ToolID==IDM_ROUNDRECT_F)
  749. 749          {
  750. 750            SelectObject(hDC, hPreBrush);
  751. 751            DeleteObject(hBrush);
  752. 752          }
  753. 753        else
  754. 754          {
  755. 755            SelectObject(hDC, hPreBrush);
  756. 756          }
  757. 757      }
  758. 758 }
  759. 759 
  760. 760 
  761. 761 
  762. 762 void DrawPencil(HDC hDC, HMENU hMenu)
  763. 763 {
  764. 764    MoveTo(hDC, PrePoint.x, PrePoint.y);
  765. 765    LineTo(hDC, CurPoint.x, CurPoint.y);
  766. 766 
  767. 767    if (! CanUndo)
  768. 768      {
  769. 769        EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  770. 770        CanUndo = TRUE;
  771. 771      }
  772. 772 }
  773. 773 
  774. 774 
  775. 775 
  776. 776 void DrawLine(HDC hDC, HMENU hMenu, BOOL bSure)
  777. 777 {
  778. 778    int  nDrawMode;
  779. 779 
  780. 780    if (! bSure)
  781. 781      {
  782. 782        nDrawMode = SetROP2(hDC, R2_NOT);
  783. 783 
  784. 784        MoveTo(hDC, OrgPoint.x, OrgPoint.y);
  785. 785        LineTo(hDC, PrePoint.x, PrePoint.y);
  786. 786 
  787. 787        MoveTo(hDC, OrgPoint.x, OrgPoint.y);
  788. 788        LineTo(hDC, CurPoint.x, CurPoint.y);
  789. 789 
  790. 790        SetROP2(hDC, nDrawMode);
  791. 791      }
  792. 792    else
  793. 793      {
  794. 794        MoveTo(hDC, OrgPoint.x, OrgPoint.y);
  795. 795        LineTo(hDC, CurPoint.x, CurPoint.y);
  796. 796 
  797. 797        if (! CanUndo)
  798. 798          {
  799. 799            EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  800. 800            CanUndo = TRUE;
  801. 801          }
  802. 802      }
  803. 803 }
  804. 804 
  805. 805 
  806. 806 
  807. 807 void Erase(HDC hDC, HMENU hMenu, BOOL bSure)
  808. 808 {
  809. 809    int  nDrawMode;
  810. 810 
  811. 811    if (! bSure)
  812. 812      {
  813. 813        nDrawMode = SetROP2(hDC, R2_NOT);
  814. 814 
  815. 815        Rectangle(hDC, OrgPoint.x, OrgPoint.y,
  816. 816                       PrePoint.x, PrePoint.y);
  817. 817 
  818. 818        Rectangle(hDC, OrgPoint.x, OrgPoint.y,
  819. 819                       CurPoint.x, CurPoint.y);
  820. 820 
  821. 821        SetROP2(hDC, nDrawMode);
  822. 822      }
  823. 823    else
  824. 824      {
  825. 825        PatBlt(hDC, OrgPoint.x, OrgPoint.y,
  826. 826                    CurPoint.x-OrgPoint.x,
  827. 827                    CurPoint.y-OrgPoint.y,
  828. 828                    WHITENESS);
  829. 829 
  830. 830        if (! CanUndo)
  831. 831          {
  832. 832            EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  833. 833            CanUndo = TRUE;
  834. 834          }
  835. 835      }
  836. 836 }
  837. 837 
  838. 838 
  839. 839 
  840. 840 void DrawRect(HDC hDC, HMENU hMenu, BOOL bSure)
  841. 841 {
  842. 842    int  nDrawMode;
  843. 843 
  844. 844    if (! bSure)
  845. 845      {
  846. 846        nDrawMode = SetROP2(hDC, R2_NOT);
  847. 847 
  848. 848        Rectangle(hDC, OrgPoint.x, OrgPoint.y,
  849. 849                       PrePoint.x, PrePoint.y);
  850. 850 
  851. 851        Rectangle(hDC, OrgPoint.x, OrgPoint.y,
  852. 852                       CurPoint.x, CurPoint.y);
  853. 853 
  854. 854        SetROP2(hDC, nDrawMode);
  855. 855      }
  856. 856    else
  857. 857      {
  858. 858        Rectangle(hDC, OrgPoint.x, OrgPoint.y,
  859. 859                       CurPoint.x, CurPoint.y);
  860. 860 
  861. 861        if (! CanUndo)
  862. 862          {
  863. 863            EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  864. 864            CanUndo = TRUE;
  865. 865          }
  866. 866      }
  867. 867 }
  868. 868 
  869. 869 
  870. 870 
  871. 871 void DrawEllip(HDC hDC, HMENU hMenu, BOOL bSure)
  872. 872 {
  873. 873    int  nDrawMode;
  874. 874 
  875. 875    if (! bSure)
  876. 876      {
  877. 877        nDrawMode = SetROP2(hDC, R2_NOT);
  878. 878 
  879. 879        Ellipse(hDC, OrgPoint.x, OrgPoint.y,
  880. 880                     PrePoint.x, PrePoint.y);
  881. 881 
  882. 882        Ellipse(hDC, OrgPoint.x, OrgPoint.y,
  883. 883                     CurPoint.x, CurPoint.y);
  884. 884 
  885. 885        SetROP2(hDC, nDrawMode);
  886. 886      }
  887. 887    else
  888. 888      {
  889. 889        Ellipse(hDC, OrgPoint.x, OrgPoint.y,
  890. 890                     CurPoint.x, CurPoint.y);
  891. 891 
  892. 892        if (! CanUndo)
  893. 893          {
  894. 894            EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  895. 895            CanUndo = TRUE;
  896. 896          }
  897. 897      }
  898. 898 }
  899. 899 
  900. 900 
  901. 901 
  902. 902 void DrawRoundRect(HDC hDC, HMENU hMenu, BOOL bSure)
  903. 903 {
  904. 904    int  nDrawMode;
  905. 905 
  906. 906    if (! bSure)
  907. 907      {
  908. 908        nDrawMode = SetROP2(hDC, R2_NOT);
  909. 909 
  910. 910        RoundRect(hDC, OrgPoint.x, OrgPoint.y,
  911. 911                       PrePoint.x, PrePoint.y,
  912. 912                       (PrePoint.x-OrgPoint.x)/4,
  913. 913                       (PrePoint.y-OrgPoint.y)/4);
  914. 914 
  915. 915        RoundRect(hDC, OrgPoint.x, OrgPoint.y,
  916. 916                       CurPoint.x, CurPoint.y,
  917. 917                       (CurPoint.x-OrgPoint.x)/4,
  918. 918                       (CurPoint.y-OrgPoint.y)/4);
  919. 919 
  920. 920        SetROP2(hDC, nDrawMode);
  921. 921      }
  922. 922    else
  923. 923      {
  924. 924        RoundRect(hDC, OrgPoint.x, OrgPoint.y,
  925. 925                       CurPoint.x, CurPoint.y,
  926. 926                       (CurPoint.x-OrgPoint.x)/4,
  927. 927                       (CurPoint.y-OrgPoint.y)/4);
  928. 928 
  929. 929        if (! CanUndo)
  930. 930          {
  931. 931            EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  932. 932            CanUndo = TRUE;
  933. 933          }
  934. 934      }
  935. 935 }
  936. 936 
  937. 937 
  938. 938 
  939. 939 void DrawCircle(HDC hDC, HMENU hMenu, BOOL bSure)
  940. 940 {
  941. 941    int    nDrawMode;
  942. 942    int    nLogPixSx, nLogPixSy;
  943. 943    int    Width, Height;
  944. 944    int    SignX, SignY;
  945. 945 
  946. 946    nLogPixSx = GetDeviceCaps(hDC, LOGPIXELSX);
  947. 947    nLogPixSy = GetDeviceCaps(hDC, LOGPIXELSY);
  948. 948 
  949. 949    Width  = CurPoint.x - OrgPoint.x;
  950. 950    Height = CurPoint.y - OrgPoint.y;
  951. 951    SignX  = (Width  >= 0 ? 1 : -1);
  952. 952    SignY  = (Height >= 0 ? 1 : -1);
  953. 953 
  954. 954    if (fabs((float) Width/nLogPixSx) >
  955. 955        fabs((float) Height/nLogPixSy) )
  956. 956       {
  957. 957          CurPoint.x = OrgPoint.x + (float)
  958. 958            fabs(Height) * nLogPixSx / nLogPixSy * SignX;
  959. 959       }
  960. 960    else
  961. 961       {
  962. 962          CurPoint.y = OrgPoint.y + (float)
  963. 963            fabs(Width) * nLogPixSy / nLogPixSx * SignY;
  964. 964       }
  965. 965 
  966. 966 
  967. 967    if (! bSure)
  968. 968      {
  969. 969        nDrawMode = SetROP2(hDC, R2_NOT);
  970. 970 
  971. 971        Ellipse(hDC, OrgPoint.x, OrgPoint.y,
  972. 972                     PrePoint.x, PrePoint.y);
  973. 973 
  974. 974        Ellipse(hDC, OrgPoint.x, OrgPoint.y,
  975. 975                     CurPoint.x, CurPoint.y);
  976. 976 
  977. 977        SetROP2(hDC, nDrawMode);
  978. 978      }
  979. 979    else
  980. 980      {
  981. 981        Ellipse(hDC, OrgPoint.x, OrgPoint.y,
  982. 982                     CurPoint.x, CurPoint.y);
  983. 983 
  984. 984        if (! CanUndo)
  985. 985          {
  986. 986            EnableMenuItem(hMenu, IDM_UNDO, MF_ENABLED);
  987. 987            CanUndo = TRUE;
  988. 988          }
  989. 989      }
  990. 990 }