大家好,我想开发一个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
#endifint 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);
MAT2 mat2;
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) ;
}
我查了若干资料,参考一个已有的程序做,未达到理想的效果。我把代码附上,请各位帮忙指点迷津,感谢!代码如下:
/*---------------------------------------------------------
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
#endifint 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);
MAT2 mat2;
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) ;
}
解决方案 »
- windows socket 传输异常,求解惑?
- 如何用GDI+ 绘制管道呀??
- 哪位兄弟能帮忙下载 codejock xtreme toolkit pro 2009 非常感谢!!!(另外开帖送上500分 ^_^)
- 怎么将CString的变量复值到char* 的变量里
- 怎么显示子对话框,让其在所有程序窗口的最上端,并激活为当前窗口?
- 我靠!!!!!!我的INFORMIX数据库坏了,HELP ME!!!
- 怎么让CControlBar不能floating,即只让他dock...
- 简单的数据库问题
- 我想写一个时钟程序,但不知从那里下手,请各位高手指点一下。
- 急救:怪错
- MFC文档管理器求助
- win32 API 串口接收数据问题
看看GetGlyphOutline的说明
http://baike.baidu.com/view/1080765.htm
If GGO_BITMAP, GGO_GRAY2_BITMAP, GGO_GRAY4_BITMAP, GGO_GRAY8_BITMAP, or GGO_NATIVE is specified and the function succeeds, the return value is greater than zero; otherwise, the return value is GDI_ERROR. If one of these flags is specified and the buffer size or address is zero, the return value specifies the required buffer size, in bytes. If GGO_METRICS is specified and the function fails, the return value is GDI_ERROR. 我刚才测试了一下,果然返回的是GDI_ERROR,我再修改代码试试。
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.
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 ;
这里注意两个问题
一、如kaizi65535在13楼所说,字体需要是TrueType的
二、你要确定你预获取的字符被你选择的字体所支持