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

GDI/图象编程

开发平台:

Visual C++

  1.   1 #include "paint.h"
  2.   2 #include <windows.h>
  3.   3 
  4.   4 int  FAR PASCAL EnumFaces(LPLOGFONT, LPTEXTMETRIC,
  5.   5                           short, LPSTR);
  6.   6 int  FAR PASCAL EnumSizes(LPLOGFONT, LPTEXTMETRIC,
  7.   7                           short, LPSTR);
  8.   8 void MakeFontMenu(HWND);
  9.   9 void MakeSizeMenu(HWND);
  10.  10 void FillStrokeSize();
  11.  11 void ChangeFont(HWND);
  12.  12 
  13.  13 struct {
  14.  14    int  FaceNum;
  15.  15    char FaceName[MAXFACES][LF_FACESIZE];
  16.  16    BOOL bRaster[MAXFACES];
  17.  17 } FontFace;
  18.  18 
  19.  19 struct {
  20.  20    int          SizeNum;
  21.  21    LOGFONT      lf[MAXSIZES];
  22.  22    TEXTMETRIC   tm[MAXSIZES];
  23.  23 } FontSize;
  24.  24 
  25.  25 extern HANDLE hInst;
  26.  26 
  27.  27 extern HDC    hMemDC;
  28.  28 extern int    OX, OY;
  29.  29 extern int    CX, CY;
  30.  30 
  31.  31 extern int    nLogPixSx;
  32.  32 extern int    nLogPixSy;
  33.  33 
  34.  34 extern BOOL   CanUndo;
  35.  35 
  36.  36 int    FaceID;
  37.  37 int    SizeID;
  38.  38 BOOL   bBold, bItalic;
  39.  39 BOOL   bUnderLine, bStrikeOut;
  40.  40 BOOL   bNormal;
  41.  41 
  42.  42 HBITMAP hBoldBM, hItalicBM;
  43.  43 HBITMAP hUnderlineBM, hStrikeOutBM;
  44.  44 
  45.  45 HFONT  hCurFont;
  46.  46 BOOL   bFontExist = FALSE;
  47.  47 
  48.  48 BOOL   bTextWorking = FALSE;
  49.  49 int    CharX, CharY;
  50.  50 int    CharPosX, CharPosY;
  51.  51 BOOL   bCaret = FALSE;
  52.  52 
  53.  53 char   Buffer[160];
  54.  54 POINT  Start;
  55.  55 int    nChar;
  56.  56 
  57.  57 TEXTMETRIC CurTM;
  58.  58 
  59.  59 void ChooseFontMenu(HWND hWnd, WORD wParam)
  60.  60 {
  61.  61    HMENU  hMenu;
  62.  62 
  63.  63    hMenu = GetMenu(hWnd);
  64.  64 
  65.  65    if (wParam>=IDM_FONT && wParam<IDM_FONT+MAXFACES)
  66.  66      {
  67.  67        if (wParam != FaceID)
  68.  68          {
  69.  69            CheckMenuItem(hMenu, FaceID, MF_UNCHECKED);
  70.  70            FaceID = wParam;
  71.  71            CheckMenuItem(hMenu, FaceID, MF_CHECKED);
  72.  72 
  73.  73            MakeSizeMenu(hWnd);
  74.  74          }
  75.  75        return;
  76.  76      }
  77.  77    else
  78.  78    if (wParam>=IDM_SIZE && wParam<IDM_SIZE+MAXSIZES)
  79.  79      {
  80.  80        if (wParam != SizeID)
  81.  81          {
  82.  82            CheckMenuItem(hMenu, SizeID, MF_UNCHECKED);
  83.  83            SizeID = wParam;
  84.  84            CheckMenuItem(hMenu, SizeID, MF_CHECKED);
  85.  85          }
  86.  86      }
  87.  87    else
  88.  88      switch (wParam)
  89.  89        {
  90.  90           case IDM_BOLD :
  91.  91                  if (bNormal)
  92.  92                    {
  93.  93                      bNormal = FALSE;
  94.  94                      CheckMenuItem(hMenu, IDM_NORM,
  95.  95                                    MF_UNCHECKED);
  96.  96                    }
  97.  97                  if (bBold)
  98.  98                     CheckMenuItem(hMenu, wParam,
  99.  99                                   MF_UNCHECKED);
  100. 100                  else
  101. 101                     CheckMenuItem(hMenu, wParam,
  102. 102                                   MF_CHECKED);
  103. 103 
  104. 104                  bBold = ! bBold;
  105. 105                  break;
  106. 106 
  107. 107           case IDM_ITALIC :
  108. 108                  if (bNormal)
  109. 109                    {
  110. 110                      bNormal = FALSE;
  111. 111                      CheckMenuItem(hMenu, IDM_NORM,
  112. 112                                    MF_UNCHECKED);
  113. 113                    }
  114. 114                  if (bItalic)
  115. 115                    CheckMenuItem(hMenu, wParam,
  116. 116                                  MF_UNCHECKED);
  117. 117                  else
  118. 118                    CheckMenuItem(hMenu, wParam,
  119. 119                                  MF_CHECKED);
  120. 120 
  121. 121                  bItalic = ! bItalic;
  122. 122                  break;
  123. 123 
  124. 124           case IDM_UNDERLINE :
  125. 125                  if (bNormal)
  126. 126                    {
  127. 127                      bNormal = FALSE;
  128. 128                      CheckMenuItem(hMenu, IDM_NORM,
  129. 129                                    MF_UNCHECKED);
  130. 130                    }
  131. 131                  if (bUnderLine)
  132. 132                    CheckMenuItem(hMenu, wParam,
  133. 133                                  MF_UNCHECKED);
  134. 134                  else
  135. 135                    CheckMenuItem(hMenu, wParam,
  136. 136                                  MF_CHECKED);
  137. 137 
  138. 138                  bUnderLine =  ! bUnderLine;
  139. 139                  break;
  140. 140 
  141. 141           case IDM_STRIKEOUT :
  142. 142                  if (bNormal)
  143. 143                    {
  144. 144                      bNormal = FALSE;
  145. 145                      CheckMenuItem(hMenu, IDM_NORM,
  146. 146                                    MF_UNCHECKED);
  147. 147                    }
  148. 148                  if (bStrikeOut)
  149. 149                    CheckMenuItem(hMenu, wParam,
  150. 150                                  MF_UNCHECKED);
  151. 151                  else
  152. 152                    CheckMenuItem(hMenu, wParam,
  153. 153                                  MF_CHECKED);
  154. 154 
  155. 155                  bStrikeOut =  ! bStrikeOut;
  156. 156                  break;
  157. 157 
  158. 158           case IDM_NORM :
  159. 159                  if (bNormal)
  160. 160                    break;
  161. 161 
  162. 162                  bNormal = TRUE;
  163. 163                  CheckMenuItem(hMenu, IDM_NORM,
  164. 164                                MF_CHECKED);
  165. 165 
  166. 166                  bBold = bItalic = FALSE;
  167. 167                  bUnderLine = bStrikeOut = FALSE;
  168. 168                  CheckMenuItem(hMenu, IDM_BOLD,
  169. 169                                MF_UNCHECKED);
  170. 170                  CheckMenuItem(hMenu, IDM_ITALIC,
  171. 171                                MF_UNCHECKED);
  172. 172                  CheckMenuItem(hMenu, IDM_UNDERLINE,
  173. 173                                MF_UNCHECKED);
  174. 174                  CheckMenuItem(hMenu, IDM_STRIKEOUT,
  175. 175                                MF_UNCHECKED);
  176. 176 
  177. 177                  break;
  178. 178        }
  179. 179 
  180. 180    if (bTextWorking)
  181. 181      ChangeFont(hWnd);
  182. 182 }
  183. 183 
  184. 184 
  185. 185 
  186. 186 int FAR PASCAL EnumFaces(LPLOGFONT lpLF, LPTEXTMETRIC lpTM,
  187. 187                          short nType, LPSTR lpData)
  188. 188 {
  189. 189    lstrcpy(FontFace.FaceName[FontFace.FaceNum],
  190. 190            lpLF->lfFaceName);
  191. 191    FontFace.bRaster[FontFace.FaceNum] = nType & 1;
  192. 192 
  193. 193    FontFace.FaceNum++;
  194. 194 
  195. 195    if (FontFace.FaceNum >= MAXFACES)
  196. 196       return (0);
  197. 197    return (1);
  198. 198 }
  199. 199 
  200. 200 
  201. 201 int FAR PASCAL EnumSizes(LPLOGFONT lpLF, LPTEXTMETRIC lpTM,
  202. 202                          short nType, LPSTR lpData)
  203. 203 {
  204. 204    if (nLogPixSx != lpTM->tmDigitizedAspectX ||
  205. 205        nLogPixSy != lpTM->tmDigitizedAspectY)
  206. 206      return (1);
  207. 207 
  208. 208    FontSize.lf[FontSize.SizeNum] = *lpLF;
  209. 209    FontSize.tm[FontSize.SizeNum] = *lpTM;
  210. 210 
  211. 211    FontSize.SizeNum++;
  212. 212 
  213. 213    if (FontSize.SizeNum >= MAXSIZES)
  214. 214       return (0);
  215. 215    return (1);
  216. 216 }
  217. 217 
  218. 218 
  219. 219 void MakeFontMenu(HWND hWnd)
  220. 220 {
  221. 221    int     i;
  222. 222    HDC     hDC;
  223. 223    HMENU   hMenu, hPopMenu;
  224. 224    FARPROC lpEnumFaces;
  225. 225 
  226. 226    FontFace.FaceNum = 0;
  227. 227    lpEnumFaces = MakeProcInstance(EnumFaces, hInst);
  228. 228 
  229. 229    hDC = GetDC(hWnd);
  230. 230    EnumFonts(hDC, NULL, lpEnumFaces, NULL);
  231. 231    ReleaseDC(hWnd, hDC);
  232. 232 
  233. 233    hMenu    = GetMenu(hWnd);
  234. 234    hPopMenu = GetSubMenu(hMenu, FONTMENU);
  235. 235 
  236. 236    DeleteMenu(hPopMenu, 0, MF_BYPOSITION);
  237. 237 
  238. 238    for (i=0; i<FontFace.FaceNum; i++)
  239. 239      AppendMenu(hPopMenu, 0, IDM_FONT+i,
  240. 240                 FontFace.FaceName[i]);
  241. 241 
  242. 242    FaceID = -1;
  243. 243    SendMessage(hWnd, WM_COMMAND, IDM_FONT, 0L);
  244. 244 
  245. 245    MakeSizeMenu(hWnd);
  246. 246 }
  247. 247 
  248. 248 
  249. 249 void MakeSizeMenu(HWND hWnd)
  250. 250 {
  251. 251    int     i;
  252. 252    HDC     hDC;
  253. 253    HMENU   hMenu, hPopMenu;
  254. 254    FARPROC lpEnumSizes;
  255. 255    char    szStr[10];
  256. 256    static  LOGFONT DefLF;
  257. 257 
  258. 258    FontSize.SizeNum = 0;
  259. 259    lpEnumSizes = MakeProcInstance(EnumSizes, hInst);
  260. 260 
  261. 261    if (FontFace.bRaster[FaceID-IDM_FONT])
  262. 262      {
  263. 263        hDC = GetDC(hWnd);
  264. 264        EnumFonts(hDC, FontFace.FaceName[FaceID-IDM_FONT],
  265. 265                  lpEnumSizes, NULL);
  266. 266        ReleaseDC(hWnd, hDC);
  267. 267      }
  268. 268    else
  269. 269       FillStrokeSize();
  270. 270 
  271. 271    hMenu    = GetMenu(hWnd);
  272. 272    hPopMenu = GetSubMenu(hMenu, SIZEMENU);
  273. 273 
  274. 274    while (GetMenuItemCount(hPopMenu) > 0)
  275. 275      DeleteMenu(hPopMenu, 0, MF_BYPOSITION);
  276. 276 
  277. 277    if (FontSize.SizeNum)
  278. 278       for (i=0; i<FontSize.SizeNum; i++)
  279. 279         {
  280. 280           sprintf(szStr, "%2d",
  281. 281                   ((FontSize.tm[i].tmHeight -
  282. 282                     FontSize.tm[i].tmInternalLeading)*72
  283. 283                     +nLogPixSy/2) / nLogPixSy) ;
  284. 284           AppendMenu(hPopMenu, 0, IDM_SIZE+i, szStr);
  285. 285         }
  286. 286    else
  287. 287       {
  288. 288         FontSize.lf[0] = DefLF;
  289. 289         lstrcpy(FontSize.lf[0].lfFaceName,
  290. 290                 FontFace.FaceName[FaceID-IDM_FONT]);
  291. 291         AppendMenu(hPopMenu, 0, IDM_SIZE, "Default");
  292. 292       }
  293. 293 
  294. 294    SizeID = -1;
  295. 295    SendMessage(hWnd, WM_COMMAND, IDM_SIZE, 0L);
  296. 296 }
  297. 297 
  298. 298 
  299. 299 void FillStrokeSize()
  300. 300 {
  301. 301    int    i;
  302. 302    static LOGFONT DefLF;
  303. 303    int    StrokeSize[] = {  8, 10, 12, 14, 16,
  304. 304                            18, 20, 22, 24, 26,
  305. 305                            28, 30, 32, 34, 36 };
  306. 306 
  307. 307    FontSize.SizeNum = sizeof(StrokeSize)/sizeof(int);
  308. 308 
  309. 309    for (i=0; i<FontSize.SizeNum; i++)
  310. 310      {
  311. 311        FontSize.lf[i] = DefLF;
  312. 312 
  313. 313        lstrcpy(FontSize.lf[i].lfFaceName,
  314. 314                   FontFace.FaceName[FaceID-IDM_FONT]);
  315. 315        FontSize.lf[i].lfCharSet = OEM_CHARSET;
  316. 316        FontSize.lf[i].lfHeight = StrokeSize[i]*nLogPixSy/72;
  317. 317 
  318. 318        FontSize.tm[i].tmHeight = StrokeSize[i]*nLogPixSy/72;
  319. 319        FontSize.tm[i].tmInternalLeading = 0;
  320. 320      }
  321. 321 }
  322. 322 
  323. 323 
  324. 324 void MakeStyleMenu(HMENU hMenu)
  325. 325 {
  326. 326    HMENU hStyleMenu;
  327. 327 
  328. 328    hBoldBM      = LoadBitmap(hInst, "Bold");
  329. 329    hItalicBM    = LoadBitmap(hInst, "Italic");
  330. 330    hUnderlineBM = LoadBitmap(hInst, "Underline");
  331. 331    hStrikeOutBM = LoadBitmap(hInst, "StrikeOut");
  332. 332 
  333. 333    hStyleMenu = GetSubMenu(hMenu, STYLEMENU);
  334. 334    AppendMenu(hStyleMenu, MF_BITMAP, IDM_BOLD,
  335. 335               (LPSTR)(LONG)hBoldBM);
  336. 336    AppendMenu(hStyleMenu, MF_BITMAP, IDM_ITALIC,
  337. 337               (LPSTR)(LONG)hItalicBM);
  338. 338    AppendMenu(hStyleMenu, MF_BITMAP, IDM_UNDERLINE,
  339. 339               (LPSTR)(LONG)hUnderlineBM);
  340. 340    AppendMenu(hStyleMenu, MF_BITMAP, IDM_STRIKEOUT,
  341. 341               (LPSTR)(LONG)hStrikeOutBM);
  342. 342 }
  343. 343 
  344. 344 
  345. 345 void DeleteStyleMenu()
  346. 346 {
  347. 347    DeleteObject(hBoldBM);
  348. 348    DeleteObject(hItalicBM);
  349. 349    DeleteObject(hUnderlineBM);
  350. 350    DeleteObject(hStrikeOutBM);
  351. 351 }
  352. 352 
  353. 353 
  354. 354 HFONT CreateCurFont()
  355. 355 {
  356. 356    LOGFONT  lf;
  357. 357    HFONT    hFont;
  358. 358 
  359. 359    lf = FontSize.lf[SizeID-IDM_SIZE];
  360. 360 
  361. 361    lf.lfWeight = bBold ? 700 : 400;
  362. 362    lf.lfItalic = bItalic;
  363. 363    lf.lfUnderline = bUnderLine;
  364. 364    lf.lfStrikeOut = bStrikeOut;
  365. 365 
  366. 366    hFont = CreateFontIndirect(&lf);
  367. 367    return (hFont);
  368. 368 }
  369. 369 
  370. 370 
  371. 371 void BeginWrite(HWND hWnd, int X, int Y)
  372. 372 {
  373. 373    HDC  hDC;
  374. 374 
  375. 375    bTextWorking = TRUE;
  376. 376    CharPosX = X;
  377. 377    CharPosY = Y;
  378. 378 
  379. 379    if (bFontExist)
  380. 380      DeleteObject(hCurFont);
  381. 381 
  382. 382    hCurFont = CreateCurFont();
  383. 383    bFontExist = TRUE;
  384. 384 
  385. 385    hDC = GetDC(hWnd);
  386. 386    SelectObject(hDC, hCurFont);
  387. 387    GetTextMetrics(hDC, &CurTM);
  388. 388 
  389. 389    CharX = CurTM.tmAveCharWidth;
  390. 390    CharY = CurTM.tmHeight;
  391. 391 
  392. 392    if (bCaret)
  393. 393      {
  394. 394        HideCaret(hWnd);
  395. 395        DestroyCaret();
  396. 396      }
  397. 397 
  398. 398    BackUpGraph(hDC, GetMenu(hWnd), OX, OY, CX, CY, 0, 0);
  399. 399 
  400. 400    CreateCaret(hWnd, NULL, 1, CharY);
  401. 401    SetCaretPos(CharPosX, CharPosY);
  402. 402    ShowCaret(hWnd);
  403. 403    bCaret = TRUE;
  404. 404 
  405. 405    nChar = 0;
  406. 406    Start.x = CharPosX;
  407. 407    Start.y = CharPosY;
  408. 408 
  409. 409    ReleaseDC(hWnd, hDC);
  410. 410 }
  411. 411 
  412. 412 
  413. 413 void EndWrite(HWND hWnd)
  414. 414 {
  415. 415    bTextWorking = FALSE;
  416. 416 
  417. 417    if (bFontExist)
  418. 418      {
  419. 419        DeleteObject(hCurFont);
  420. 420        bFontExist = FALSE;
  421. 421      }
  422. 422 
  423. 423    if (bCaret)
  424. 424      {
  425. 425        HideCaret(hWnd);
  426. 426        DestroyCaret();
  427. 427        bCaret = FALSE;
  428. 428      }
  429. 429 }
  430. 430 
  431. 431 
  432. 432 void ChangeFont(HWND hWnd)
  433. 433 {
  434. 434    HDC   hDC;
  435. 435    DWORD dwLen;
  436. 436    int   StrW, StrH;
  437. 437 
  438. 438    HideCaret(hWnd);
  439. 439    DestroyCaret();
  440. 440 
  441. 441    hDC = GetDC(hWnd);
  442. 442 
  443. 443    SelectObject(hDC, hCurFont);
  444. 444    StrW = LOWORD(GetTextExtent(hDC, Buffer, nChar));
  445. 445    StrH = CurTM.tmHeight;
  446. 446 
  447. 447    DeleteObject(hCurFont);
  448. 448 
  449. 449    hCurFont = CreateCurFont();
  450. 450    SelectObject(hDC, hCurFont);
  451. 451    GetTextMetrics(hDC, &CurTM);
  452. 452 
  453. 453    if (nChar > 0)
  454. 454      {
  455. 455        BitBlt(hDC, Start.x-20, Start.y, StrW+21, StrH,
  456. 456               hMemDC, OX+Start.x-20, OY+Start.y,
  457. 457               SRCCOPY);
  458. 458 
  459. 459        TextOut(hDC, Start.x, Start.y, Buffer, nChar);
  460. 460        CharPosX = Start.x - CurTM.tmOverhang +
  461. 461                LOWORD(GetTextExtent(hDC, Buffer, nChar));
  462. 462      }
  463. 463 
  464. 464    CharX = CurTM.tmAveCharWidth;
  465. 465    CharY = CurTM.tmHeight;
  466. 466 
  467. 467    CreateCaret(hWnd, NULL, 1, CharY);
  468. 468    SetCaretPos(CharPosX, CharPosY);
  469. 469    ShowCaret(hWnd);
  470. 470 
  471. 471    ReleaseDC(hWnd, hDC);
  472. 472 }
  473. 473 
  474. 474 void ProcessChar(HWND hWnd, WORD ch)
  475. 475 {
  476. 476    HDC  hDC;
  477. 477    int  CharWidth;
  478. 478 
  479. 479    hDC = GetDC(hWnd);
  480. 480 
  481. 481    switch (ch)
  482. 482     {
  483. 483       case 'r' : Start.y += CurTM.tmHeight;
  484. 484                   CharPosX = Start.x;
  485. 485                   CharPosY = Start.y;
  486. 486                   SetCaretPos(CharPosX, CharPosY);
  487. 487                   nChar = 0;
  488. 488                   break;
  489. 489 
  490. 490       case 'b' : if (nChar == 0) break;
  491. 491 
  492. 492                   HideCaret(hWnd);
  493. 493                   SelectObject(hDC, hCurFont);
  494. 494 
  495. 495                   CharWidth = LOWORD(
  496. 496                     GetTextExtent(hDC, Buffer+nChar-1, 1));
  497. 497                   CharPosX -= (CharWidth-CurTM.tmOverhang);
  498. 498                   BitBlt(hDC,
  499. 499                          CharPosX-20, CharPosY,
  500. 500                          CharWidth+21, CurTM.tmHeight,
  501. 501                          hMemDC,
  502. 502                          OX+CharPosX-20, OY+CharPosY,
  503. 503                          SRCCOPY);
  504. 504 
  505. 505                   nChar--;
  506. 506                   if (nChar > 0)
  507. 507                      TextOut(hDC,
  508. 508                              Start.x, CharPosY,
  509. 509                              Buffer, nChar);
  510. 510 
  511. 511                   SetCaretPos(CharPosX, CharPosY);
  512. 512                   ShowCaret(hWnd);
  513. 513                   break;
  514. 514 
  515. 515       default   : Buffer[nChar] = ch;
  516. 516                   HideCaret(hWnd);
  517. 517 
  518. 518                   SelectObject(hDC, hCurFont);
  519. 519                   TextOut(hDC, CharPosX, CharPosY,
  520. 520                           Buffer+nChar, 1);
  521. 521 
  522. 522                   CharWidth = LOWORD(
  523. 523                     GetTextExtent(hDC, Buffer+nChar, 1))
  524. 524                     - CurTM.tmOverhang;
  525. 525                   CharPosX += CharWidth;
  526. 526                   nChar ++;
  527. 527 
  528. 528                   SetCaretPos(CharPosX, CharPosY);
  529. 529                   ShowCaret(hWnd);
  530. 530 
  531. 531                   if (! CanUndo)
  532. 532                     {
  533. 533                       EnableMenuItem(GetMenu(hWnd),
  534. 534                                 IDM_UNDO, MF_ENABLED);
  535. 535                       CanUndo = TRUE;
  536. 536                     }
  537. 537                   break;
  538. 538     }
  539. 539 
  540. 540    ReleaseDC(hWnd, hDC);
  541. 541 }