首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

windows api 获取字库点阵的有关问题

2012-04-27 
windows api 获取字库点阵的问题大家好,我想开发一个windows应用程序,这个程序在绘制的时候从字库中取出一

windows api 获取字库点阵的问题
大家好,我想开发一个windows应用程序,这个程序在绘制的时候从字库中取出一个汉字的位图数据,然后绘制出来。
我查了若干资料,参考一个已有的程序做,未达到理想的效果。我把代码附上,请各位帮忙指点迷津,感谢!

代码如下:


/*---------------------
  DEVCAPS1.C -- Device Capabilities Display Program No. 1
  (c) Charles Petzold, 1998
  ---------------------*/

#include <windows.h>
#include "tchar.h"


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

#define NUM 1000
#ifdef UNICODE
#define GetGlyphOutline GetGlyphOutlineW
#else
#define GetGlyphOutline GetGlyphOutlineA
#endif

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  PSTR szCmdLine, int iCmdShow)
{
  static TCHAR szAppName[] = TEXT ("draw line sample1 ") ;
  HWND hwnd ;
  MSG msg ;
  WNDCLASS wndclass ;
   
  wndclass.style = CS_HREDRAW | CS_VREDRAW ;
  wndclass.lpfnWndProc = WndProc ;
  wndclass.cbClsExtra = 0 ;
  wndclass.cbWndExtra = 0 ;
  wndclass.hInstance = hInstance ;
  wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
  wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  wndclass.lpszMenuName = NULL ;
  wndclass.lpszClassName = szAppName ;
   
  if (!RegisterClass (&wndclass))
  {
  MessageBox (NULL, TEXT ("This program requires Windows NT!"),
  szAppName, MB_ICONERROR) ;
  return 0 ;
  }
   
  hwnd = CreateWindow (szAppName, TEXT ("draw line sample1 "),
  WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT, CW_USEDEFAULT,
  CW_USEDEFAULT, CW_USEDEFAULT,
  NULL, NULL, hInstance, NULL) ;
   
  ShowWindow (hwnd, iCmdShow) ;
  UpdateWindow (hwnd) ;
   
  while (GetMessage (&msg, NULL, 0, 0))
  {
  TranslateMessage (&msg) ;
  DispatchMessage (&msg) ;
  }
  return msg.wParam ;
}



 FIXED FixedFromDouble(double d)
 {

  long l;

  l = (long) (d * 65536L);
  return *(FIXED *)&l;

 }


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  static int cxChar, cxCaps, cyChar,cxClient,cyClient;
  TCHAR szBuffer[10],chText;
  HDC hdc ;
  UINT i,k ;
int j;
  PAINTSTRUCT ps ;
  TEXTMETRIC tm ;
RECT rcClient;
POINT currentPosition;
POINT apt[NUM];
POINT apt1[4]={0,0,50,200,150,300,400,247};
HFONT hFont,oldFont;
DWORD dwBufSize;

   
  switch (message)
  {
case WM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
return 0;

  case WM_CREATE:
  hdc = GetDC (hwnd) ;
  GetTextMetrics (hdc, &tm) ;
  cxChar = tm.tmAveCharWidth ;
  cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
  cyChar = tm.tmHeight + tm.tmExternalLeading ;  
  ReleaseDC (hwnd, hdc) ;
  return 0 ;
   


  case WM_PAINT:
  hdc = BeginPaint (hwnd, &ps) ;
hFont=(HFONT)GetStockObject(ANSI_VAR_FONT);
oldFont=(HFONT)SelectObject(hdc,hFont);
MAT2mat2;
mat2.eM11 = FixedFromDouble(2);
mat2.eM12 = FixedFromDouble(0);
  mat2.eM21 = FixedFromDouble(0);
  mat2.eM22 = FixedFromDouble(2);
 
GLYPHMETRICS gm;
//chText=L'泰';
chText =L'泰';
dwBufSize=GetGlyphOutline(hdc,chText,GGO_BITMAP,&gm,0L,NULL,&mat2);
if(dwBufSize>0 && dwBufSize<0xFFFF)
{
//char* lpBuf=NULL;
//lpBuf=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwBufSize);

LPBYTE lpBuf=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwBufSize);
 

if(lpBuf)
{
GetGlyphOutline(hdc,chText,GGO_BITMAP,&gm,dwBufSize,lpBuf,&mat2);

int nByteCount = ((gm.gmBlackBoxX +31) >> 5) << 2;

for (i = 0; i<gm.gmBlackBoxY; i++)
{
for (j = 0; j<nByteCount; j++)
{
BYTE btCode = lpBuf[i* nByteCount + j];

for (k = 0; k<8; k++)
{

if (btCode & (0x80>>k))
  {  
SetPixel(hdc,j*8+k,i*1,RGB(244,0,0));
  }
  else
  {
  SetPixel(hdc,j*8+k,i*1,RGB(0,0,0));
  } 

}
}
}
HeapFree(GetProcessHeap(),0,lpBuf);
}
}
SelectObject(hdc,oldFont);
DeleteObject(hFont);  
  EndPaint (hwnd, &ps) ;
  return 0 ;
  case WM_DESTROY:
  PostQuitMessage (0) ;
  return 0 ;
  }
  return DefWindowProc (hwnd, message, wParam, lParam) ;
}


[解决办法]
是不是GetGlyphOutline调用失败了
看看GetGlyphOutline的说明
http://baike.baidu.com/view/1080765.htm
[解决办法]

GetGlyphOutline
The GetGlyphOutline function retrieves the outline or bitmap for a character in the TrueType font that is selected into the specified device context. 

程序中的这两行:hFont=(HFONT)GetStockObject(ANSI_VAR_FONT);
oldFont=(HFONT)SelectObject(hdc,hFont);

其中ANSI_VAR_FONT不是TrueType font

所以改用:DEFAULT_GUI_FONT 

DEFAULT_GUI_FONT Default font for user interface objects such as menus and dialog boxes. This is MS Sans Serif. Compare this with SYSTEM_FONT.
[解决办法]
WM_PAINT分支这样修改

C/C++ code
case WM_PAINT:        hdc        = BeginPaint (hwnd, &ps) ;        hFont    = (HFONT)GetStockObject(DEFAULT_GUI_FONT);        oldFont=(HFONT)SelectObject(hdc, hFont);        MAT2 mat2;        mat2.eM11 = FixedFromDouble(2);        mat2.eM12 = FixedFromDouble(0);        mat2.eM21 = FixedFromDouble(0);        mat2.eM22 = FixedFromDouble(2);        GLYPHMETRICS gm;        chText =L'A';        dwBufSize=GetGlyphOutline(hdc, chText, GGO_BITMAP, &gm, 0L, NULL, &mat2);        if(dwBufSize>0 && dwBufSize<0xFFFF)        {            LPBYTE lpBuf=(LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);            if(lpBuf)            {                GetGlyphOutline(hdc, chText, GGO_BITMAP, &gm, dwBufSize, lpBuf, &mat2);                int nByteCount = ((gm.gmBlackBoxX +31) >> 5) << 2;                for (i = 0; i<gm.gmBlackBoxY; i++)                {                    for (j = 0; j<nByteCount; j++)                    {                        BYTE btCode = lpBuf[i* nByteCount + j];                        for (k = 0; k<8; k++)                        {                            if (btCode & (0x80>>k))                            {                                   SetPixel(hdc,j*8+k,i*1,RGB(244,0,0));                            }                            else                            {                                SetPixel(hdc,j*8+k,i*1,RGB(0,0,0));                            }                          }                    }                }                HeapFree(GetProcessHeap(),0,lpBuf);            }        }        SelectObject(hdc,oldFont);        DeleteObject(hFont);           EndPaint (hwnd, &ps) ;        return 0 ; 

热点排行