RemoveFontResource的问题,有一定难度,谁能解决,多多得分,可以另外开贴给分!!!

sans 2001-12-19 04:29:51
一个简单的基于对话框的程序,在初始化软件时使用AddFontResource增加一个字体,在程序中使用了此字体,在退出程序时在使用RemoveFontResource时系统出现错误提示,忽略两次后软件仍然能够正常退出,但这个错误只在Win98第一、第二版中会发生,在WinMe下不会,这是为什么?
程序代码大致如下:
在OnInitDialog()中:
AddFontResource( "f:\\myfonts\\myfont01.ttf" );//注意没有安装到系统字体目录下。
m_fMyFont.CreateFont( 32, ....,"MyFont01" );//字体名为MyFont01,m_fMyFont为一个CFont类。
m_Text.SetFont( &m_fMyFont ); //m_Text是一个CStatic控件
m_Btn.SetFont( &m_fMyFont ); //m_Btn是一个CButton控件
...
在退出软件时:
RemoveFontResource( "f:\\myfonts\\myfont01.ttf" );//这个调用出错,但如果用GetLastError取得的却是“正确执行了操作”。
如果将m_Text.SetFont一句屏蔽,而不屏蔽m_Btn.SetFont,那么RemoveFontResource就不会出错了。
我真的很搞不明白,谁能帮助我?
...全文
426 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
sans 2001-12-19
  • 打赏
  • 举报
回复
还不能分开给,就全给你吧!
sans 2001-12-19
  • 打赏
  • 举报
回复
有,多谢xiaoxiaohan(萧晓寒),先给你50分。
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
VC光盘
SAMPLES\VC98\SDK\SDKTOOLS\ANIEDIT
SAMPLES\VC98\SDK\WINBASE\IPC\DDEML\CLOCK
都用了
你有吗?没有就留下mail我给你发过去。
sans 2001-12-19
  • 打赏
  • 举报
回复
等我研究一下...
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复

/******************************************************************************* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/

/*
* CLOCK.C - Windows DDEML Clock
*
* DDE Transactions:
* ----------------
* Service: Clock
* Topic : Time
* Item : Now
*
* Use Request or Advise to get the time or use Poke to change the time.
* Time Format Hour:Minute:Seconds where
* Hour = 0-23
* Minute = 0-59
* Seconds = 0-59
*/

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "windows.h"
#include <ddeml.h>
#include "clock.h"


DWORD idInst = 0;

CLOCKDISPSTRUCT ClockDisp;

HANDLE hInst;
HWND hWindow;

HBRUSH hbrBackground;
HBRUSH hbrColorWindow;
HBRUSH hbrColorBlack;
HBRUSH hbrForeground;
HFONT hFont;
HPEN hpenForeground;
HPEN hpenBackground;

INT nLeadZero = 0;
INT TimerID = 1; /* number used for timer-id */
INT clockRadius;
INT HorzRes;
INT VertRes;

LONG aspectD;
LONG aspectN;

CHAR szBuffer[BUFLEN]; /* buffer for stringtable stuff */
CHAR szFontFile[20];
CHAR szIniFile[20];
CHAR szSection[30];

POINT clockCenter;

TIME oTime;

RECT clockRect;
RECT rCoordRect;

HDDEDATA CALLBACK DdeCallback(WORD usType, WORD usFmt, HCONV hConv, HSZ hsz1,
HSZ hsz2, HDDEDATA hData, DWORD lData1, DWORD lData2);
HSZ hszTime, hszNow, hszClock; /* Hszs for DDEML use */

/*
* Function Prototypes
*/

LONG APIENTRY ClockWndProc(register HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

void NEAR PASCAL ClockCreate(HWND hWnd);
BOOL NEAR PASCAL ClockInit(HANDLE hInstance);
void NEAR PASCAL ClockPaint(HWND hWnd, register HDC hDC, INT hint);
void NEAR PASCAL ClockSize(register HWND hWnd,INT newWidth,INT newHeight, WORD SizeWord);
void NEAR PASCAL ClockTimer(HWND hWnd, UINT msg);
void NEAR PASCAL CompClockDim(void);
void NEAR PASCAL CreateTools(void);
void NEAR PASCAL DeleteTools(void);
void NEAR PASCAL DrawBorder(HWND hWnd, register HDC hDC);
void NEAR PASCAL DrawFace(HDC hDC);
void NEAR PASCAL DrawHand(register HDC hDC, INT pos, HPEN hPen, INT scale, INT patMode);
void NEAR PASCAL DrawFatHand(register HDC hDC, INT pos, HPEN hPen, BOOL hHand);
void NEAR PASCAL FormatInit(register HANDLE hInstance, BOOL fModeChange);
void NEAR PASCAL SizeFont(HWND hWnd, INT newHeight, INT newWidth, INT wlen);
void NEAR PASCAL SetMenuBar( HWND hWnd );


/*
* CreateTools()
*/

void NEAR PASCAL CreateTools(void)

{
hbrForeground = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT));
hbrColorWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
hbrColorBlack = CreateSolidBrush(0L);
hbrBackground = hbrColorWindow;
hpenForeground = CreatePen(0, 1, GetSysColor(COLOR_WINDOWTEXT));
hpenBackground = CreatePen(0, 1, GetSysColor(COLOR_WINDOW));
}


/*
* DeleteTools()
*/

void NEAR PASCAL DeleteTools(void)

{
DeleteObject(hbrForeground);
DeleteObject(hbrColorWindow);
DeleteObject(hbrColorBlack);
DeleteObject(hpenForeground);
DeleteObject(hpenBackground);
}


/*
* SizeFont() - size font according to window size
*/

void NEAR PASCAL SizeFont(HWND hWnd, INT newHeight, INT newWidth, INT wlen)
{
register HDC hDC;
TEXTMETRIC tm;
LOGFONT FontStruct;

hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);

if (ClockDisp.wFormat == IDM_DIGITAL) {
if (hFont != NULL)
DeleteObject(hFont);

FontStruct.lfUnderline = FALSE;
FontStruct.lfStrikeOut = FALSE;
FontStruct.lfItalic = FALSE;
FontStruct.lfEscapement = FALSE;
FontStruct.lfOrientation = FALSE;
FontStruct.lfOutPrecision = OUT_DEFAULT_PRECIS;
FontStruct.lfClipPrecision = CLIP_DEFAULT_PRECIS;

/* Note that the numbers used in this formula depend on the
* size of the numbers in the fonts which are 12 vert, 7 horz.
*/
if (!ClockDisp.bIconic) {
FontStruct.lfHeight = (SHORT)min(newHeight/2, 45);

/* The formula at the end is somewhat empirical. */
FontStruct.lfWidth = (SHORT)min(25, newWidth/(wlen*3/2));

/* This if is here because of a problem where: if a clock
* existed with a maximum size font, any new clock with a
* smaller client area would get the same font that would not
* fit in the Window. So here, if the width does not match
* maximum font dimensions, don't use the maximum height.
*/
if (FontStruct.lfWidth != 25 && FontStruct.lfHeight == 45)
FontStruct.lfHeight = 40;
}
else {
FontStruct.lfHeight = (SHORT)(newHeight/3);
FontStruct.lfWidth = (SHORT)(newWidth/5);
}

FontStruct.lfCharSet = ANSI_CHARSET;
FontStruct.lfQuality = DRAFT_QUALITY;
FontStruct.lfWeight = FW_NORMAL;
FontStruct.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;

lstrcpy(FontStruct.lfFaceName, "DIGITAL");

hFont = CreateFontIndirect(&FontStruct);

SelectObject(hDC, hFont);
GetTextMetrics(hDC, &tm);
SelectObject(hDC, GetStockObject(SYSTEM_FONT));
}

ReleaseDC(hWnd, hDC);

/* Compute placement for digital text. */
ClockDisp.line1.x = (newWidth) / 2;
ClockDisp.line1.y = (newHeight - (tm.tmHeight)) / 2;
ClockDisp.yline2 = ClockDisp.line1.y + tm.tmHeight;
}


/*
* CompClockDim() - Recompute the clock's dimensions.
*/

void NEAR PASCAL CompClockDim(void)

{
INT i;
register INT tWidth;
register INT tHeight;

tWidth = clockRect.right - clockRect.left;
tHeight = clockRect.bottom - clockRect.top;

if (tWidth > (INT)((tHeight * aspectD) / aspectN)) {
i = (INT)((tHeight * aspectD) / aspectN);
clockRect.left += (tWidth - i) >> 1;
clockRect.right = clockRect.left + i;
}
else {
i = (INT)((tWidth * aspectN) / aspectD);
clockRect.top += (tHeight - i) >> 1;
clockRect.bottom = clockRect.top + i;
}
}


/*
* ClockSize()
*/

void NEAR PASCAL ClockSize(register HWND hWnd,
INT newWidth,
INT newHeight,
WORD SizeWord)
{
SetRect((LPRECT)&(clockRect), 0, 0, newWidth, newHeight);
CompClockDim();

if (SizeWord == SIZEICONIC) {
/* Update once every 1/2 minute in the iconic state */
KillTimer(hWnd, TimerID);
SetTimer(hWnd, TimerID, (WORD)ICON_TLEN, 0L);
ClockDisp.bIconic = TRUE;
}
else if (ClockDisp.bIconic) {
/* Update every 1/2 second in the opened state. */
KillTimer(hWnd, TimerID);
SetTimer(hWnd, TimerID, OPEN_TLEN, 0L);
ClockDisp.bIconic = FALSE;
}

/* Compute where the digital readout should go. */
SizeFont(hWnd, newHeight, newWidth, ClockDisp.wDigTimeLen);
}


/*
* DrawBorder() - Draws a Red Border around either clock.
*/

void NEAR PASCAL DrawBorder(HWND hWnd, register HDC hDC)
{
RECT Rect;
HPEN hPen;

GetClientRect(hWnd, (LPRECT) &Rect);

hPen = CreatePen(PS_SOLID, (ClockDisp.bIconic) ? 1 : 2,
(ClockDisp.bColor) ? RGB(255,0,0) : RGB(255,255,255));

SelectObject(hDC, hPen);
Rectangle(hDC, Rect.left+1, Rect.top+1, Rect.right, Rect.bottom);
SelectObject(hDC, GetStockObject(BLACK_PEN));

DeleteObject(hPen);

/* Draw an external black border on an icon without killing the client area. */
if (ClockDisp.bIconic) {
MoveToEx(hDC, Rect.left, Rect.top, NULL);
LineTo(hDC, Rect.left, Rect.bottom);
LineTo(hDC, Rect.right, Rect.bottom);
LineTo(hDC, Rect.right, Rect.top);
LineTo(hDC, Rect.left, Rect.top);
}
}


/*
* DrawFace()
*/

void NEAR PASCAL DrawFace(HDC hDC)
{
INT i;
RECT tRect;
INT blobHeight, blobWidth;

blobWidth = (INT)((MAXBLOBWIDTH * (LONG)(clockRect.right - clockRect.left)) / HorzRes);
blobHeight = (INT)((blobWidth * aspectN) / aspectD);

if (blobHeight < 2)
blobHeight = 1;

if (blobWidth < 2)
blobWidth = 2;

InflateRect((LPRECT)&clockRect, -(blobHeight >> 1), -(blobWidth >> 1));

clockRadius = (clockRect.right - clockRect.left-6) >> 1;
clockCenter.y = clockRect.top + ((clockRect.bottom - clockRect.top) >> 1);
clockCenter.x = clockRect.left + clockRadius+3;

for (i=0; i < 60; i++) {
tRect.top = (INT)(((LONG)(CirTab[i].cos) * clockRadius) / CLKSCALE + clockCenter.y);
tRect.left = (INT)(((LONG)(CirTab[i].sin) * clockRadius) / CLKSCALE + clockCenter.x);

if (i % 5) {
/* Draw a dot. */
if (blobWidth > 2 && blobHeight >= 2) {
tRect.right = tRect.left + 1;
tRect.bottom = tRect.top + 1;
FillRect(hDC, (LPRECT)&tRect, hbrForeground);
}
}
else {
tRect.right = tRect.left + blobWidth;
tRect.bottom = tRect.top + blobHeight;
OffsetRect((LPRECT)&tRect, -(blobWidth >> 1) , -(blobHeight >> 1));
FillRect(hDC, (LPRECT)&tRect, hbrForeground);
}
}
InflateRect((LPRECT)&clockRect, (blobHeight >> 1), (blobWidth >> 1));
}


/*
* DrawHand() - Draw the second hand using XOR mode.
*/

void NEAR PASCAL DrawHand(register HDC hDC,
INT pos,
HPEN hPen,
INT scale,
INT patMode)
{
INT radius;

MoveToEx(hDC, clockCenter.x, clockCenter.y, NULL);
radius = (INT)(((LONG)clockRadius * scale) / 100);
SetROP2(hDC, patMode);
SelectObject(hDC, hPen);

LineTo(hDC, clockCenter.x + (INT)(((LONG)(CirTab[pos].sin) * (radius)) / CLKSCALE),
clockCenter.y + (INT)(((LONG)(CirTab[pos].cos) * (radius)) / CLKSCALE));
}


/*
* DrawFatHand() - Draws either hour or minute hand.
*/

void NEAR PASCAL DrawFatHand(register HDC hDC, INT pos, HPEN hPen, BOOL hHand)
{
register INT m;
INT n;
INT scale;
POINT tip;
POINT stip;

SetROP2(hDC, R2_COPYPEN);

SelectObject(hDC, hPen);

scale = hHand ? 7 : 5;

n = (pos+15)%60;
m = (INT)((((LONG)clockRadius*scale) / 100));
stip.y = (INT)((LONG)(CirTab[n].cos) * m / CLKSCALE);
stip.x = (INT)((LONG)(CirTab[n].sin) * m / CLKSCALE);

scale = hHand ? 65 : 80;
tip.y = (INT)((LONG)(CirTab[pos].cos) * (((LONG)clockRadius * scale) / 100) / CLKSCALE);
tip.x = (INT)((LONG)(CirTab[pos].sin) * (((LONG)clockRadius * scale) / 100) / CLKSCALE);

MoveToEx(hDC, clockCenter.x+stip.x, clockCenter.y+stip.y, NULL);
LineTo(hDC, clockCenter.x+tip.x, clockCenter.y+tip.y);
MoveToEx(hDC, clockCenter.x-stip.x, clockCenter.y-stip.y, NULL);
LineTo(hDC, clockCenter.x+tip.x, clockCenter.y+tip.y);

scale = hHand ? 15 : 20;

n = (pos + 30) % 60;
m = (INT)(((LONG)clockRadius * scale) / 100);
tip.y = (INT)((LONG)(CirTab[n].cos) * m / CLKSCALE);
tip.x = (INT)((LONG)(CirTab[n].sin) * m / CLKSCALE);
MoveToEx(hDC, clockCenter.x+stip.x, clockCenter.y+stip.y, NULL);
LineTo(hDC, clockCenter.x+tip.x, clockCenter.y+tip.y);
MoveToEx(hDC, clockCenter.x-stip.x, clockCenter.y-stip.y, NULL);
LineTo(hDC, clockCenter.x+tip.x, clockCenter.y+tip.y);
}


/*
* ClockPaint()
*/

void NEAR PASCAL ClockPaint(HWND hWnd, register HDC hDC, INT hint)
{
INT hour;
CHAR *pszTime;
RECT Rect;
TIME nTime;
DWORD rgbCol;
HBRUSH hBr;

GetClientRect(hWnd, (LPRECT) &Rect);

GetTime(&nTime);

if (ClockDisp.wFormat == IDM_DIGITAL) { /* Digital Display */
if (hint == REPAINT || ClockDisp.bIconic) {
SelectObject(hDC, GetStockObject(BLACK_BRUSH));
DrawBorder(hWnd, hDC);

/* Set old values as undefined, so entire clock updated. */
oTime.hour24 = 25;
oTime.minute = 60;
oTime.ampm = 2;
}

if (oTime.hour24 != nTime.hour24) {
if (ClockDisp.wTimeFormat)
hour = nTime.hour24;
else
hour = nTime.hour12;

ClockDisp.szDigTime[0] = (CHAR)('0' + hour / 10);
ClockDisp.szDigTime[1] = (CHAR)('0' + hour % 10);
}

if (oTime.minute != nTime.minute) {
ClockDisp.szDigTime[3] = (CHAR)('0' + nTime.minute / 10);
ClockDisp.szDigTime[4] = (CHAR)('0' + nTime.minute % 10);
}

/* Kill Leading zero if needed. */
if (nLeadZero == 0 && ClockDisp.szDigTime[0] == '0')
pszTime = ClockDisp.szDigTime + 1;
else
pszTime = ClockDisp.szDigTime;

SetTextColor(hDC, (ClockDisp.bColor) ? RGB(0,255,0) : RGB(255,255,255));
SetBkColor(hDC, 0L);
SetTextAlign(hDC, TA_CENTER);

ClockDisp.wDigTimeLen = (WORD)((ClockDisp.bIconic ? 5 : 8) + ClockDisp.szDigTime - pszTime);

/* Is the font ready yet? */
if (hFont == 0 || ClockDisp.bNewFont) {
/* Create a suitable font */
SizeFont(hWnd, Rect.bottom - Rect.top, Rect.right - Rect.left, ClockDisp.wDigTimeLen);
ClockDisp.bNewFont = FALSE;
}

SelectObject(hDC, hFont);
ClockDisp.szDigTime[6] = (CHAR)('0' + nTime.second / 10);
ClockDisp.szDigTime[7] = (CHAR)('0' + nTime.second % 10);

Rect.left += 4;
Rect.right -= 4;
Rect.top = ClockDisp.line1.y;
Rect.bottom = ClockDisp.yline2;
ExtTextOut(hDC, ClockDisp.line1.x, ClockDisp.line1.y, ETO_OPAQUE | ETO_CLIPPED,
(LPRECT)&Rect, pszTime, (UINT)ClockDisp.wDigTimeLen, (LPINT)NULL);
SelectObject(hDC, GetStockObject(SYSTEM_FONT));
}
else {
/* Analog display */
SetBkMode(hDC, TRANSPARENT);
if (hint == REPAINT) {
SetBkMode(hDC, OPAQUE);
/* When switching from Digital to analog, the brush selected
* continued to be black; So, the current background is to be
* selected;
* Fix for Bug #6385 -- SANKAR -- 11-26-89 */
SelectObject(hDC, hbrBackground);

/* Make a temp brush to color the background. This is to
* force use of a solid color so the hand motion is painted
* correctly.
*/
rgbCol = GetNearestColor(hDC, GetSysColor(COLOR_WINDOW));
hBr = CreateSolidBrush(rgbCol);

FillRect(hDC, &Rect, hBr);

DeleteObject(hBr);

SetBkMode(hDC, TRANSPARENT);

DrawBorder(hWnd, hDC);
DrawFace(hDC);
DrawFatHand(hDC, oTime.hour * 5 + (oTime.minute / 12), hpenForeground, HHAND);
DrawFatHand(hDC, oTime.minute, hpenForeground, MHAND);

if (!ClockDisp.bIconic) /* Draw the second hand. */
DrawHand(hDC, oTime.second, hpenBackground, SECONDSCALE, R2_NOT);

/* NOTE: Don't update oTime in this case! */

return;
}
else if (hint == HANDPAINT) {
if ((!ClockDisp.bIconic) && nTime.second != oTime.second) /* Erase the old second hand. */
DrawHand(hDC, oTime.second, hpenBackground, SECONDSCALE, R2_NOT);

if (nTime.minute != oTime.minute || nTime.hour != oTime.hour) {
if (ClockDisp.bIconic) {
DrawHand(hDC, oTime.minute, hpenBackground, MINUTESCALE, R2_COPYPEN);
DrawHand(hDC, oTime.hour * 5 + (oTime.minute / 12), hpenBackground, HOURSCALE, R2_COPYPEN);
DrawHand(hDC, nTime.minute, hpenForeground, MINUTESCALE, R2_COPYPEN);
DrawHand(hDC, nTime.hour * 5 + (nTime.minute / 12), hpenForeground, HOURSCALE, R2_COPYPEN);
}
else {
DrawFatHand(hDC, oTime.minute, hpenBackground, MHAND);
DrawFatHand(hDC, oTime.hour*5+(oTime.minute/12), hpenBackground, HHAND);
DrawFatHand(hDC, nTime.minute, hpenForeground, MHAND);
DrawFatHand(hDC, (nTime.hour) * 5 + (nTime.minute / 12), hpenForeground, HHAND );
}
}

if (!ClockDisp.bIconic && nTime.second != oTime.second) /* Draw new second hand */
DrawHand(hDC, nTime.second, hpenBackground, SECONDSCALE, R2_NOT);
}
}
oTime = nTime;
}


/*
* ClockTimer()
*
* msg - timer ID
*
* Called by windows to tell CLOCK there has been a time change.
*
*/

void NEAR PASCAL ClockTimer(HWND hWnd, UINT msg)
{
HDC hDC;
TIME nTime;

GetTime(&nTime);

/* It's possible to change any part of the system at any time
* through the Control Panel. So we check everything.
*/
if (((nTime.second == oTime.second) || ClockDisp.bIconic) &&
(nTime.minute == oTime.minute) &&
(nTime.hour24 == oTime.hour24))
return;

hDC = GetDC(hWnd);
ClockPaint(hWnd, hDC, HANDPAINT);
ReleaseDC(hWnd, hDC);
DdePostAdvise(idInst, hszTime, hszNow);
UNREFERENCED_PARAMETER(msg);
}


/*
* ClockCreate()
*/

void NEAR PASCAL ClockCreate(HWND hWnd)
{
INT i;
register HDC hDC;
INT HorzSize;
INT VertSize;

hDC = GetDC(hWnd);
VertRes = GetDeviceCaps(hDC, VERTRES);
HorzRes = GetDeviceCaps(hDC, HORZRES);
VertSize= GetDeviceCaps(hDC, VERTSIZE);
HorzSize= GetDeviceCaps(hDC, HORZSIZE);
ReleaseDC(hWnd, hDC);

aspectN = ((LONG)VertRes * 100) / (LONG)VertSize;
aspectD = ((LONG)HorzRes * 100) / (LONG)HorzSize;

CreateTools();

/* Scale sines for aspect ratio if this is the first instance */
for (i=0; i < 60; i++) {
CirTab[i].sin = (SHORT)((CirTab[i].sin * aspectN) / aspectD);
}
}



/*
* FormatInit() - International initialization.
*/

void NEAR PASCAL FormatInit(register HANDLE hInstance, BOOL fModeChange)
{
WORD i, ii;
CHAR szWinHeader[21], szKeyName[21], szRetVal[21];

for (i=0; i < 11; i++)
ClockDisp.szDigTime[i] = ' ';

LoadString(hInstance, IDS_INTL, (LPSTR)szWinHeader, 20);

LoadString(hInstance, IDS_ITIME, (LPSTR)szKeyName, 20);
ClockDisp.wTimeFormat = (WORD)GetProfileInt((LPSTR)szWinHeader, (LPSTR)szKeyName, 0);

LoadString(hInstance, IDS_S1159, (LPSTR)szKeyName, 20);
LoadString(hInstance, IDS_1159, (LPSTR)szRetVal, 20);
i = (WORD)GetProfileString((LPSTR)szWinHeader, (LPSTR)szKeyName, (LPSTR)szRetVal, (LPSTR)&ClockDisp.szAMPM[0][0], 7);

LoadString(hInstance, IDS_S2359, (LPSTR)szKeyName, 20);
LoadString(hInstance, IDS_2359, (LPSTR)szRetVal, 20);
ii = (WORD)GetProfileString((LPSTR)szWinHeader, (LPSTR)szKeyName, (LPSTR)szRetVal, (LPSTR)&ClockDisp.szAMPM[1][0], 7);

nLeadZero = GetProfileInt((LPSTR)szWinHeader, "iTLzero", 0);

LoadString(hInstance, IDS_STIME, (LPSTR)szKeyName, 20);
LoadString(hInstance, IDS_TIMESEP, (LPSTR)szRetVal, 20);

GetProfileString((LPSTR)szWinHeader, (LPSTR)szKeyName, (LPSTR)szRetVal, (LPSTR)szRetVal, 20);
ClockDisp.cTimeSep = szRetVal[0];

ClockDisp.szDigTime[2] = ClockDisp.cTimeSep;
ClockDisp.szDigTime[5] = ClockDisp.cTimeSep;

LoadString(hInstance, IDS_USNAME, (LPSTR)szWinHeader, 20);
LoadString(hInstance, IDS_CLKFORMAT, (LPSTR)szKeyName, 20);

/* We will read the new mode (DIGITAL/ANALOG) only during init time. */
if (fModeChange)
{
if (GetPrivateProfileInt((LPSTR)szWinHeader, (LPSTR)szKeyName, 1, (LPSTR)szIniFile))
ClockDisp.wFormat = IDM_ANALOG;
else
ClockDisp.wFormat = IDM_DIGITAL;
}

if (ClockDisp.wFormat == IDM_ANALOG)
hbrBackground = hbrColorWindow;
else
hbrBackground = hbrColorBlack;

ClockDisp.wDigTimeLen = 2+1+2+1+2+1;

if (!ClockDisp.wTimeFormat)
ClockDisp.wDigTimeLen += ((i > ii) ? (i) : (ii));
}


/*
* ClockInit()
*/

BOOL NEAR PASCAL ClockInit(HANDLE hInstance)
{
HDC hDC;
WNDCLASS ClockClass;

FormatInit(hInstance, TRUE);

ClockClass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
ClockClass.lpfnWndProc = ClockWndProc;
ClockClass.cbClsExtra = 0;
ClockClass.cbWndExtra = 0;
ClockClass.hInstance = hInstance;
ClockClass.hIcon = NULL;
ClockClass.hCursor = LoadCursor(NULL, IDC_ARROW);
ClockClass.hbrBackground = (HBRUSH) NULL;
ClockClass.lpszMenuName = (LPSTR)"Clock";
ClockClass.lpszClassName = (LPSTR)"Clock";

if (!RegisterClass((LPWNDCLASS)&ClockClass))
return(FALSE);

LoadString(hInstance, IDS_FONTFILE, (LPSTR)szFontFile, 20);
AddFontResource(szFontFile);

/* Check the number of colors that the display is capable of. */
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
ClockDisp.bColor = (GetDeviceCaps(hDC, NUMCOLORS) > 2);
ClockDisp.bColor = FALSE;
DeleteDC(hDC);

ClockDisp.bTmpHide = FALSE;
ClockDisp.bNewFont = FALSE;
ClockDisp.bColor = TRUE;
ClockDisp.bNewFont = TRUE;

return(TRUE);
}

/*
* SetMenuBar() - places or removes the menu bar, etc.
*
* Based on the flag ClockDisp.bNoTitle (ie: do we want a menu/title
* bar or not?), adds or removes the window title and menu bar:
* Gets current style, toggles the bits, and re-sets the style.
* Must then resize the window frame and show it.
*/

void NEAR PASCAL SetMenuBar( HWND hWnd )
{
static DWORD wID;
DWORD dwStyle;

dwStyle = GetWindowLong( hWnd, GWL_STYLE );
if( ClockDisp.bNoTitle ) {
/* remove caption & menu bar, etc. */
dwStyle &= ~(WS_DLGFRAME | WS_SYSMENU |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
wID = SetWindowLong( hWnd, GWL_ID, 0 );
}
else {
/* put menu bar & caption back in */
dwStyle = WS_TILEDWINDOW | dwStyle;
SetWindowLong( hWnd, GWL_ID, wID );
}
SetWindowLong( hWnd, GWL_STYLE, dwStyle );
SetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_FRAMECHANGED );
ShowWindow( hWnd, SW_SHOW );
}

/*
* AboutDlgProc()
*/

BOOL APIENTRY AboutDlgProc ( hwnd, msg, wParam, lParam )
HWND hwnd;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
switch (msg) {
case WM_INITDIALOG:
/* nothing to initialize */
break;

case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hwnd, 0);
break;

default:
return FALSE;
}
break;

default:
return(FALSE);
}

return TRUE;
}



/*
* ClockWndProc()
*/

LONG APIENTRY ClockWndProc(register HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMENU hMenu;
static CHAR szAppName[12]; /* application name buffer */
PAINTSTRUCT ps;

switch (message) {
case WM_COMMAND:
switch (wParam) {

case IDM_ANALOG:
case IDM_DIGITAL:
if ((WORD)wParam != ClockDisp.wFormat) {
/* Switch flag to other choice */
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, ClockDisp.wFormat, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ClockDisp.wFormat = (WORD) wParam, MF_BYCOMMAND | MF_CHECKED);
InvalidateRect(hWnd, (LPRECT) NULL, TRUE);
}
break;

case IDM_NOTITLE:
goto toggle_title;

case IDM_ABOUT: {
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)AboutDlgProc);
break;
}

default:
goto defproc;
}
break;

case WM_SIZE:
ClockDisp.bNewFont = TRUE;
ClockSize(hWnd, LOWORD(lParam), HIWORD(lParam), (WORD)wParam);
UpdateWindow(hWnd);
break;

case WM_QUERYDRAGICON:
return (LONG)LoadIcon(hInst, "cckk");

case WM_CLOSE:
case WM_ENDSESSION:
DestroyWindow( hWnd );
break;

case WM_DESTROY: {
CHAR szInt[10];
HCURSOR hTempCursor;

KillTimer(hWnd, TimerID);
DeleteTools();
if (hFont)
DeleteObject(hFont);
RemoveFontResource(szFontFile);

SetCapture(hWnd);
hTempCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));

if (!(IsIconic(hWnd) || IsZoomed(hWnd)))
GetWindowRect(hWnd, &rCoordRect);

/* Write new configuration to DDEMLCLK.INI */
LoadString(hInst, IDS_CLKFORMAT, (LPSTR)szBuffer, BUFLEN-1);
szInt[0] = (CHAR)('0' + (ClockDisp.wFormat == IDM_ANALOG));
szInt[1] = 0;
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)szBuffer,
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)IsIconic(hWnd));
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"Minimized",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)IsZoomed(hWnd));
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"Maximized",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.left);
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"Left",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.top);
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"Top",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.right);
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"Right",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.bottom);
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"Bottom",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)ClockDisp.bTopMost);
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"TopMost",
(LPSTR)szInt,
(LPSTR)szIniFile);
wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)ClockDisp.bNoTitle);
WritePrivateProfileString((LPSTR)szSection,
(LPSTR)"NoTitle",
(LPSTR)szInt,
(LPSTR)szIniFile);
PostQuitMessage(0);
break;
}

case WM_WININICHANGE:
/* FALSE indicates that we don't want to change the display format */
FormatInit(hInst, FALSE);
InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
break;

case WM_PAINT:
/* Added to force total repaint to solve
* problem of garbage under second hand when hidden
* by menu or popup.
*/
InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);

if (ClockDisp.wFormat == IDM_DIGITAL) {
hbrBackground = hbrColorBlack;
FillRect(ps.hdc, (LPRECT)&clockRect, hbrBackground);
}
else
hbrBackground=hbrColorWindow;

ClockPaint(hWnd, ps.hdc, REPAINT);
EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
break;

case WM_TIMECHANGE:
/* Redraw. */
InvalidateRect(hWnd, (LPRECT)NULL, TRUE);

case WM_TIMER:
ClockTimer(hWnd, (WORD)wParam);
break;

case WM_SYSCOMMAND:
switch (wParam) {

case SC_MINIMIZE:
if (!IsZoomed(hWnd))
GetWindowRect(hWnd, (LPRECT)&rCoordRect);
ClockDisp.bMinimized = TRUE;
ClockDisp.bMaximized = FALSE;
break;
case SC_MAXIMIZE:
if (!IsIconic(hWnd))
GetWindowRect(hWnd, (LPRECT)&rCoordRect);
ClockDisp.bMinimized = FALSE;
ClockDisp.bMaximized = TRUE;
break;

case IDM_TOPMOST: {
/* toggles topmost option
*/
hMenu = GetSystemMenu(hWnd, FALSE);
if( ClockDisp.bTopMost ) {
CheckMenuItem( hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_UNCHECKED );
SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
ClockDisp.bTopMost = FALSE;
}
else {
CheckMenuItem( hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_CHECKED );
SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
ClockDisp.bTopMost = TRUE;
}
break;
}

}
return(DefWindowProc(hWnd, message, wParam, lParam));
break;

case WM_MOUSEACTIVATE:
/* right button temporarily hides the window if topmost is
* enabled (window re-appears when right button is released).
* When this happens, we don't want to activate the clock window
* just before hiding it (it would look really bad), so we
* intercept the activate message.
*/
if( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
return( MA_NOACTIVATE );
else
goto defproc;
break;

case WM_RBUTTONDOWN:
case WM_NCRBUTTONDOWN:
/* right button temporarily hides the window, if the window
* is topmost, and if no menu is currently "active"
*/
if( !ClockDisp.bTmpHide && ClockDisp.bTopMost ) {
ShowWindow( hWnd, SW_HIDE );
SetCapture( hWnd );
ClockDisp.bTmpHide = TRUE;
}
break;

case WM_RBUTTONUP:
case WM_NCRBUTTONUP:
/* if window is currently hidden, right button up brings it
* back. Must make sure we show it in its previous state - ie:
* minimized, maximized or normal.
*/
if( ClockDisp.bTmpHide ) {
ReleaseCapture();
if( IsIconic(hWnd) )
ShowWindow( hWnd, SW_SHOWMINNOACTIVE );
else if( IsZoomed( hWnd ) )
ShowWindow( hWnd, SW_SHOWMAXIMIZED );
else
ShowWindow( hWnd, SW_SHOWNOACTIVATE );
ClockDisp.bTmpHide = FALSE;
}
break;

case WM_KEYDOWN:
/* ESC key toggles the menu/title bar (just like a double click
* on the client area of the window.
*/
if( (wParam == VK_ESCAPE) && !(HIWORD( lParam ) & 0x4000) )
goto toggle_title;
break;

case WM_NCLBUTTONDBLCLK:
if( !ClockDisp.bNoTitle )
/* if we have title bars etc. let the normal stuff take place */
goto defproc;

/* else: no title bars, then this is actually a request to bring
* the title bars back...
*/

/* fall through */

case WM_LBUTTONDBLCLK:
toggle_title:
ClockDisp.bNoTitle = (ClockDisp.bNoTitle ? FALSE : TRUE );
SetMenuBar( hWnd );
break;

case WM_NCHITTEST:
/* if we have no title/menu bar, clicking and dragging the client
* area moves the window. To do this, return HTCAPTION.
* Note dragging not allowed if window maximized, or if caption
* bar is present.
*/
wParam = DefWindowProc(hWnd, message, wParam, lParam);
if( ClockDisp.bNoTitle && (wParam == HTCLIENT) && !IsZoomed(hWnd) )
return HTCAPTION;
else
return wParam;

case WM_SYSCOLORCHANGE:
DeleteTools();
CreateTools();
break;

case WM_ERASEBKGND: {
RECT rect;

GetClientRect(hWnd, (LPRECT)&rect);
SelectObject((HDC)wParam, hbrBackground);
FillRect((HDC)wParam, (LPRECT)&rect, hbrBackground);
break;
}

default:
defproc:
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return(0L);
}


/*
* WinMain()
*/

INT PASCAL WinMain(
HINSTANCE hInstance,
HINSTANCE hPrev,
LPSTR lpszCmdLine,
INT cmdShow)
{
register HWND hWnd;
MSG msg;
TIME nTime;
PSTR szTooMany;
HMENU hMenu;
CHAR szTopmost[80];

LoadString(hInstance, IDS_USNAME, (LPSTR)szBuffer, BUFLEN);
LoadString(hInstance, IDS_INIFILE, (LPSTR)szIniFile, 20);
LoadString(hInstance, IDS_USNAME, (LPSTR)szSection, 30);

if (!ClockInit(hInstance))
return(FALSE);

ClockCreate((HWND)NULL);

LoadString(hInstance, IDS_APPNAME, (LPSTR)szBuffer, BUFLEN);

rCoordRect.top=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"Top",
(DWORD)-1, (LPSTR)szIniFile);
rCoordRect.left=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"Left",
(DWORD)-1, (LPSTR)szIniFile);
rCoordRect.right=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"Right",
(DWORD)-1, (LPSTR)szIniFile);
rCoordRect.bottom=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"Bottom",
(DWORD)-1, (LPSTR)szIniFile);

hWnd = CreateWindow((LPSTR)"Clock", /* The class name. */
(LPSTR)szBuffer, /* The window instance name. */
WS_TILEDWINDOW,
(rCoordRect.left < 0) ? CW_USEDEFAULT : rCoordRect.left,
(rCoordRect.top < 0) ? CW_USEDEFAULT : rCoordRect.top,
(rCoordRect.left < 0) ? (INT)( (HorzRes/3) + GetSystemMetrics(SM_CXFRAME)*2 )
: rCoordRect.right - rCoordRect.left,
(rCoordRect.left < 0) ? (INT)( (((HorzRes/3)*aspectN)/aspectD)+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFRAME)*2 )
: rCoordRect.bottom - rCoordRect.top,
NULL,
NULL,
hInstance,
(LPSTR)NULL);

hWindow=hWnd;

// Loop if control panel time being changed.
GetTime((TIME *)&nTime);
do {
GetTime((TIME *)&oTime);
} while (nTime.second == oTime.second && nTime.minute == oTime.minute &&
nTime.hour24 == oTime.hour24);

if (!SetTimer(hWnd, TimerID, OPEN_TLEN, 0L) ) {
/* Windows only supports 16 public timers */
szTooMany = (PSTR)LocalAlloc(LPTR, 160);
LoadString(hInstance, IDS_TOOMANY, (LPSTR)szTooMany, 160);
MessageBox((HWND)NULL, (LPSTR)szTooMany, (LPSTR)szBuffer, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
DeleteTools();
return(FALSE);
}

/* Add the topmost system menu item */
hMenu = GetSystemMenu( hWnd, FALSE );
AppendMenu( hMenu, MF_SEPARATOR, 0, NULL );
LoadString(hInstance, IDS_TOPMOST, szTopmost, 79);

/* Check the default setting to the clock as topmost or not */
ClockDisp.bTopMost=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"TopMost",
0, (LPSTR)szIniFile);
if( ClockDisp.bTopMost ) {
AppendMenu( hMenu, MF_ENABLED | MF_CHECKED | MF_STRING, IDM_TOPMOST,
szTopmost );
SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
else
AppendMenu( hMenu, MF_ENABLED | MF_UNCHECKED | MF_STRING, IDM_TOPMOST,
szTopmost );

/* Check the default menu item either analog or digital */
CheckMenuItem(GetMenu(hWnd), ClockDisp.wFormat, MF_BYCOMMAND | MF_CHECKED);

/* Check the default setting to show title bar or not */
ClockDisp.bNoTitle=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"NoTitle",
0, (LPSTR)szIniFile);
if( ClockDisp.bNoTitle ) {
SetMenuBar( hWnd );
}

hInst = hInstance;

/* Check the default minimized state, minimized or not */
ClockDisp.bMinimized=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"Minimized",
0, (LPSTR)szIniFile);
if (!ClockDisp.bMinimized) {
ClockDisp.bMaximized=GetPrivateProfileInt((LPSTR)szSection,
(LPSTR)"Maximized",
0, (LPSTR)szIniFile);
if (ClockDisp.bMaximized)
ShowWindow(hWnd, SW_MAXIMIZE);
else {
ShowWindow(hWnd, cmdShow);
GetWindowRect(hWnd, (LPRECT)&rCoordRect);
}
}
else
ShowWindow(hWnd, SW_MINIMIZE);

DdeInitialize(&idInst, (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback, hInstance),
CBF_FAIL_EXECUTES | CBF_SKIP_ALLNOTIFICATIONS, 0L);
hszTime = DdeCreateStringHandle(idInst, "Time", 0);
hszNow = DdeCreateStringHandle(idInst, "Now", 0);
hszClock = DdeCreateStringHandle(idInst, "Clock", 0);
DdeNameService(idInst, hszClock, 0L, DNS_REGISTER);



while (GetMessage((LPMSG)&msg, NULL, 0, 0) ) {
TranslateMessage((LPMSG)&msg);
DispatchMessage((LPMSG)&msg);
}

DdeUninitialize(idInst);

return(msg.wParam);
}


/*
* GetTime()
*/

VOID GetTime(
TIME *ptime)
{
time_t t;
struct tm *ptm;

time(&t);
ptm = localtime(&t);
ptime->second = ptm->tm_sec;
ptime->minute = ptm->tm_min;
ptime->hour12 =
ptime->hour = ptm->tm_hour > 12 ? ptm->tm_hour - 12 : ptm->tm_hour;
ptime->hour24 = ptm->tm_hour;
ptime->ampm = ptm->tm_hour > 12 ? 1 : 0;
}


/*
* DdeCallback()
*/

HDDEDATA CALLBACK DdeCallback(
WORD usType,
WORD usFmt,
HCONV hConv,
HSZ hsz1,
HSZ hsz2,
HDDEDATA hData,
DWORD lData1,
DWORD lData2)
{

static HANDLE hToken;
static TOKEN_PRIVILEGES tp;
static LUID luid;

if (usType == XTYP_CONNECT) {
return((HDDEDATA)TRUE);
}

if (usType == XTYP_WILDCONNECT) {
HDDEDATA hData;
HSZPAIR FAR *phszp;
DWORD cb;

if ((!hsz1 || hsz1 == hszTime) && (!hsz2 || hsz2 == hszClock)) {
if ((hData = DdeCreateDataHandle(idInst, NULL,
2 * sizeof(HSZPAIR), 0L, 0, 0, 0))) {
phszp = (HSZPAIR FAR *)DdeAccessData(hData, &cb);
phszp[0].hszSvc = hszClock;
phszp[0].hszTopic = hszTime;
phszp[1].hszSvc = phszp[1].hszTopic = 0;
DdeUnaccessData(hData);
return(hData);
}
}
return(0);
}

if (usFmt == CF_TEXT) {
CHAR sz[40];

if (usType == XTYP_ADVSTART || usType == XTYP_ADVSTOP) {
return((HDDEDATA)TRUE);
}

if (hsz1 == hszTime && hsz2 == hszNow) {
if (usType == XTYP_REQUEST || usType == XTYP_ADVREQ) {

itoa(oTime.hour, sz, 10);
strcat(sz, ":");
itoa(oTime.minute, &sz[strlen(sz)], 10);
strcat(sz, ":");
itoa(oTime.second, &sz[strlen(sz)], 10);
return(DdeCreateDataHandle(idInst, (LPBYTE)sz, strlen(sz) + 1, 0L,
hszNow, CF_TEXT, 0));
}
if (usType == XTYP_POKE) {
SYSTEMTIME SysTime;

DdeGetData(hData, (LPBYTE)sz, 40L, 0L);
GetLocalTime(&SysTime);
sscanf(sz, "%2d:%2d:%2d", &SysTime.wHour, &SysTime.wMinute, &SysTime.wSecond);

/* enable system-time privilege, set time, disable privilege */
OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ;
LookupPrivilegeValue( NULL, "SeSystemTimePrivilege", &luid );
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges( hToken, FALSE, &tp,
sizeof(TOKEN_PRIVILEGES), NULL, NULL );
SetLocalTime(&SysTime);
AdjustTokenPrivileges( hToken, TRUE, &tp,
sizeof(TOKEN_PRIVILEGES), NULL, NULL );

DdePostAdvise(idInst, hszTime, hszNow);
return((HDDEDATA)DDE_FACK);
}
}
}
return(0);

UNREFERENCED_PARAMETER(lData1);
UNREFERENCED_PARAMETER(lData2);
UNREFERENCED_PARAMETER(hConv);
}
sans 2001-12-19
  • 打赏
  • 举报
回复
我也就只RemoveFontResource了一次,可就是连这一次也不行。
hh97888675 2001-12-19
  • 打赏
  • 举报
回复
两次用的是一个地址,所以你只能RemoveFontResource一次。
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
我看到一个用RemoveFontResource的例子。
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
我遇到过这样的情况,定义一个局部变量,更改字体不起作用。
如:
void DrawText()
{
CFont f;
......
setfont(f);
......
}
一旦退出函数就不起作用了。
而改为
void DrawText()
{
static CFont f;
......
setfont(f);
......
}
才一直有用,就是说用CFont自己释放是可以的,不知道对你有没有用。
sans 2001-12-19
  • 打赏
  • 举报
回复
如何彻底关闭一个字体呢?
sans 2001-12-19
  • 打赏
  • 举报
回复
实际上,即使只对一个CStatic控件进行SetFont,而去掉所有其它控件,RemoveFontResource仍然会有问题,而且只在Win98下出现,我经过仔细研究发现,在Win98下如果在DC中SelectObject我增加的字体,然后再用这个字体DrawText后,RemoveFontResource就会出问题,似乎对正在使用的字体RemoveFontResource就会出问题,在WinMe的RemoveFontResource中,如果字体正在使用,系统会先关闭它,就不会出问题了,那么我如何彻底关闭一个字体呢?对于一个CFont类,使用成员函数DeleteObject
是不起作用的,即使这样也不行:
CFont * pFont = new CFont();
pFont->CreateFont(...
.....
delete pFont;
也不能彻底关闭一个字体。
如何彻底关闭一个字体呢?
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
把编码给全点,我帮你试试
sans 2001-12-19
  • 打赏
  • 举报
回复
To:xiaoxiaohan(萧晓寒) 
只要屏蔽掉m_Text.SetFont,即使我对多个m_Btn进行SetFont:
m_Btn1.SetFont
m_Btn2.SetFont
...
m_Btn10.SetFont
那么RemoveFontResource也不会有问题,但一旦加入了CStatic控件就会出问题,即使一个也会。
另外RemoveFontResource也只能调用一次,调用第二次返回调用失败。
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
你看一看将m_Btn.SetFont一句屏蔽,而不屏蔽m_Text.SetFont会有问题吗?
如果也有问题,就是RemoveFontResource多次了。
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
你是不是循环调用RemoveFontResource
就是每个控件调用一次。
sans 2001-12-19
  • 打赏
  • 举报
回复
我也就只RemoveFontResource了一次呀!
xiaoxiaohan 2001-12-19
  • 打赏
  • 举报
回复
m_Text.SetFont( &m_fMyFont ); //m_Text是一个CStatic控件
m_Btn.SetFont( &m_fMyFont ); //m_Btn是一个CButton控件
两次用的是一个地址,所以你只能RemoveFontResource一次。
三杯倒 2001-12-19
  • 打赏
  • 举报
回复
1111
API之网络函数1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同一个网络资源的连接 WNetCancelConnection 结束一个网络连接 WNetCancelConnection2 结束一个网络连接 WNetCloseEnum 结束一次枚举操作 WNetConnectionDialog 启动一个标准对话框,以便建立同网络资源的连接 WNetDisconnectDialog 启动一个标准对话框,以便断开同网络资源的连接 WNetEnumResource 枚举网络资源 WNetGetConnection 获取本地或已连接的一个资源的网络名称 WNetGetLastError 获取网络错误的扩展错误信息 WNetGetUniversalName 获取网络中一个文件的远程名称以及/或者UNC(统一命名规范)名称 WNetGetUser 获取一个网络资源用以连接的名字 WNetOpenEnum 启动对网络资源进行枚举的过程 2. API之消息函数 BroadcastSystemMessage 将一条系统消息广播给系统中所有的顶级窗口 GetMessagePos 取得消息队列中上一条消息处理完毕时的鼠标指针屏幕位置 GetMessageTime 取得消息队列中上一条消息处理完毕时的时间 PostMessage 将一条消息投递到指定窗口的消息队列 PostThreadMessage 将一条消息投递给应用程序 RegisterWindowMessage 获取配给一个字串标识符的消息编号 ReplyMessage 答复一个消息 SendMessage 调用一个窗口的窗口函数,将一条消息发给那个窗口 SendMessageCallback 将一条消息发给窗口 SendMessageTimeout 向窗口发送一条消息 SendNotifyMessage 向窗口发送一条消息 3. API之文件处理函数 CloseHandle 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等 CompareFileTime 对比两个文件的时间 CopyFile 复制文件 CreateDirectory 创建一个新目录 CreateFile 打开和创建文件、管道、邮槽、通信服务、设备以及控制台 CreateFileMapping 创建一个新的文件映射对象 DeleteFile 删除指定文件 DeviceIoControl 对设备执行指定的操作 DosDateTimeToFileTime 将DOS日期和时间值转换成一个 win32 FILETIME 值 FileTimeToDosDateTime 将一个 win32 FILETIME 值转换成DOS日期和时间值 FileTimeToLocalFileTime 将一个FILETIME结构转换成本地时间 FileTimeToSystemTime 根据一个FILETIME结构的内容,装载一个SYSTEMTIME结构 FindClose 关闭由FindFirstFile函数创建的一个搜索句柄 FindFirstFile 根据文件名查找文件 FindNextFile 根据调用FindFirstFile函数时指定的一个文件名查找下一个文件 FlushFileBuffers 针对指定的文件句柄,刷新内部文件缓冲区 FlushViewOfFile 将写入文件映射缓冲区的所有数据都刷新到磁盘 GetBinaryType 判断文件是否可以执行 GetCompressedFileSize 判断一个压缩文件在磁盘上实际占据的字节数 GetCurrentDirectory 在一个缓冲区中装载当前目录 GetDiskFreeSpace 获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量 GetDiskFreeSpaceEx 获取与一个磁盘的组织以及剩余空间容量有关的信息 GetDriveType 判断一个磁盘驱动器的类型 GetExpandedName 取得一个压缩文件的全名 GetFileAttributes 判断指定文件的属性 GetFileInformationByHandle 这个函数提供了获取文件信息的一种机制 GetFileSize 判断文件长度 GetFileTime 取得指定文件的时间信息 GetFileType 在给出文件句柄的前提下,判断文件类型 GetFileVersionInfo 从支持版本标记的一个模块里获取文件版本信息
4. API之打印函数 AbortDoc 取消一份文档的打印 AbortPrinter 删除与一台打印机关联在一起的缓冲文件 AddForm 为打印机的表单列表添加一个新表单 AddJob 用于获取一个有效的路径名,以便用它为作业创建一个后台打印文件。它也会为作业配一个作业编号 AddMonitor 为系统添加一个打印机监视器 AddPort 启动"添加端口"对话框,允许用户在系统可用端口列表中加入一个新端口 AddPrinter 在系统中添加一台新打印机 AddPrinterConnection 连接指定的打印机 AddPrinterDriver 为指定的系统添加一个打印驱动程序 AddPrintProcessor 为指定的系统添加一个打印处理器 AddPrintProvidor 为系统添加一个打印供应商 AdvancedDocumentProperties 启动打印机文档设置对话框 ClosePrinter 关闭一个打开的打印机对象 ConfigurePort 针对指定的端口,启动一个端口配置对话框 ConnectToPrinterDlg 启动连接打印机对话框,用它同访问网络的打印机连接 DeleteForm 从打印机可用表单列表中删除一个表单 DeleteMonitor 删除指定的打印监视器 DeletePort 启动"删除端口"对话框,允许用户从当前系统删除一个端口 DeletePrinter 将指定的打印机标志为从系统中删除 DeletePrinterConnection 删除与指定打印机的连接 DeletePrinterDriver 从系统删除一个打印机驱动程序 DeletePrintProcessor 从指定系统删除一个打印处理器 DeletePrintProvidor 从系统中删除一个打印供应商 DeviceCapabilities 利用这个函数可获得与一个设备的能力有关的信息 DocumentProperties 打印机配置控制函数 EndDocAPI 结束一个成功的打印作业 EndDocPrinter 在后台打印程序的级别指定一个文档的结束 EndPage 用这个函数完成一个页面的打印,并准备设备场景,以便打印下一个页 EndPagePrinter 指定一个页在打印作业中的结尾 EnumForms 枚举一台打印机可用的表单 EnumJobs 枚举打印队列中的作业 EnumMonitors 枚举可用的打印监视器 EnumPorts 枚举一个系统可用的端口 EnumPrinterDrivers 枚举指定系统中已安装的打印机驱动程序 EnumPrinters 枚举系统中安装的打印机 EnumPrintProcessorDatatypes 枚举由一个打印处理器支持的数据类型 EnumPrintProcessors 枚举系统中可用的打印处理器 Escape 设备控制函数 FindClosePrinterChangeNotification 关闭用FindFirstPrinterChangeNotification函数获取的一个打印机通告对象 FindFirstPrinterChangeNotification 创建一个新的改变通告对象,以便我们注意打印机状态的各种变化 FindNextPrinterChangeNotification 用这个函数判断触发一次打印机改变通告信号的原因 FreePrinterNotifyInfo 释放由FindNextPrinterChangeNotification函数配的一个缓冲区 GetForm 取得与指定表单有关的信息 GetJob 获取与指定作业有关的信息 GetPrinter 取得与指定打印机有关的信息 GetPrinterData 为打印机设置注册表配置信息 GetPrinterDriver 针对指定的打印机,获取与打印机驱动程序有关的信息 GetPrinterDriverDirectory 判断指定系统中包含了打印机驱动程序的目录是什么 GetPrintProcessorDirectory 判断指定系统中包含了打印机处理器驱动程序及文件的目录 OpenPrinter 打开指定的打印机,并获取打印机的句柄 PrinterMessageBox 在拥有指定打印作业的系统上显示一个打印机出错消息框 PrinterProperties 启动打印机属性对话框,以便对打印机进行配置 ReadPrinter 从打印机读入数据 ResetDC 重设一个设备场景 ResetPrinter 改变指定打印机的默认数据类型及文档设置 ScheduleJob 提交一个要打印的作业 SetAbortProc 为Windows指定取消函数的地址 SetForm 为指定的表单设置信息 SetJob 对一个打印作业的状态进行控制 SetPrinter 对一台打印机的状态进行控制 SetPrinterData 设置打印机的注册表配置信息 StartDoc 开始一个打印作业 StartDocPrinter 在后台打印的级别启动一个新文档 StartPage 打印一个新页前要先调用这个函数 StartPagePrinter 在打印作业中指定一个新页的开始 WritePrinter 将发送目录中的数据写入打印机 5. API之文本和字体函数 AddFontResource 在Windows系统中添加一种字体资源 CreateFont 用指定的属性创建一种逻辑字体 CreateFontIndirect 用指定的属性创建一种逻辑字体 CreateScalableFontResource 为一种TureType字体创建一个资源文件,以便能用API函数AddFontResource将其加入Windows系统 DrawText 将文本描绘到指定的矩形中 DrawTextEx 与DrawText相似,只是加入了更多的功能 EnumFontFamilies 列举指定设备可用的字体 EnumFontFamiliesEx 列举指定设备可用的字体 EnumFonts 列举指定设备可用的字体 ExtTextOut 经过扩展的文本描绘函数。也请参考SetTextAlign函数 GetAspectRatioFilterEx 用SetMapperFlags要求Windows只选择与设备当前纵横比相符的光栅字体时,本函数可判断纵横比大小 GetCharABCWidths 判断TureType字体中一个或多个字符的A-B-C大小 GetCharABCWidthsFloat 查询一种字体中一个或多个字符的A-B-C尺寸 GetCharacterPlacement 该函数用于了解如何用一个给定的字符显示一个字串 GetCharWidth 调查字体中一个或多个字符的宽度 GetFontData 接收一种可缩放字体文件的数据 GetFontLanguageInfo 返回目前选入指定设备场景中的字体的信息 GetGlyphOutline 取得TureType字体中构成一个字符的曲线信息 GetKerningPairs 取得指定字体的字距信息 GetOutlineTextMetrics 接收与TureType字体内部特征有关的详细信息 GetRasterizerCaps 了解系统是否有能力支持可缩放的字体 GetTabbedTextExtent 判断一个字串占据的范围,同时考虑制表站扩充的因素 GetTextAlign 接收一个设备场景当前的文本对齐标志 GetTextCharacterExtra 判断额外字符间距的当前值 GetTextCharset 接收当前选入指定设备场景的字体的字符集标识符 GetTextCharsetInfo 获取与当前选定字体的字符集有关的详细信息 GetTextColor 判断当前字体颜色。通常也称为"前景色" GetTextExtentExPoint 判断要填入指定区域的字符数量。也用一个数组装载每个字符的范围信息 GetTextExtentPoint 判断一个字串的大小(范围) GetTextFace 获取一种字体的字样名 GetTextMetrics 获取与选入一种设备场景的物理字体有关的信息 GrayString 描绘一个以灰色显示的字串。通常由Windows用于标识禁止状态 PolyTextOut 描绘一系列字串 RemoveFontResource 从Windows系统中删除一种字体资源 SetMapperFlags Windows对字体进行映射时,可用该函数选择与目标设备的纵横比相符的光栅字体 SetTextAlign 设置文本对齐方式,并指定在文本输出过程中使用设备场景的当前位置 SetTextCharacterExtra 描绘文本的时候,指定要在字符间插入的额外间距 SetTextColor 设置当前文本颜色。这种颜色也称为"前景色" SetTextJustification 通过指定一个文本行应占据的额外空间,可用这个函数对文本进行两端对齐处理 TabbedTextOut 支持制表站的一个文本描绘函数 TextOut 文本绘图函数 6. API之菜单函数 AppendMenu 在指定的菜单里添加一个菜单项 CheckMenuItem 复选或撤消复选指定的菜单条目 CheckMenuRadioItem 指定一个菜单条目被复选成"单选"项目 CreateMenu 创建新菜单 CreatePopupMenu 创建一个空的弹出式菜单 DeleteMenu 删除指定的菜单条目 DestroyMenu 删除指定的菜单 DrawMenuBar 为指定的窗口重画菜单 EnableMenuItem 允许或禁止指定的菜单条目 GetMenu 取得窗口中一个菜单的句柄 GetMenuCheckMarkDimensions 返回一个菜单复选符的大小 GetMenuContextHelpId 取得一个菜单的帮助场景ID GetMenuDefaultItem 判断菜单中的哪个条目是默认条目 GetMenuItemCount 返回菜单中条目(菜单项)的数量 GetMenuItemID 返回位于菜单中指定位置处的条目的菜单ID GetMenuItemInfo 取得(接收)与一个菜单条目有关的特定信息 GetMenuItemRect 在一个矩形中装载指定菜单条目的屏幕坐标信息 GetMenuState 取得与指定菜单条目状态有关的信息 GetMenuString 取得指定菜单条目的字串 GetSubMenu 取得一个弹出式菜单的句柄,它位于菜单中指定的位置 GetSystemMenu 取得指定窗口的系统菜单的句柄 HiliteMenuItem 控制顶级菜单条目的加亮显示状态 InsertMenu 在菜单的指定位置处插入一个菜单条目,并根据需要将其他条目向下移动 InsertMenuItem 插入一个新菜单条目 IsMenu 判断指定的句柄是否为一个菜单的句柄 LoadMenu 从指定的模块或应用程序实例中载入一个菜单 LoadMenuIndirect 载入一个菜单 MenuItemFromPoint 判断哪个菜单条目包含了屏幕上一个指定的点 ModifyMenu 改变菜单条目 RemoveMenu 删除指定的菜单条目 SetMenu 设置窗口菜单 SetMenuContextHelpId 设置一个菜单的帮助场景ID SetMenuDefaultItem 将一个菜单条目设为默认条目 SetMenuItemBitmaps 设置一幅特定位图,令其在指定的菜单条目中使用,代替标准的复选符号(√) SetMenuItemInfo 为一个菜单条目设置指定的信息 TrackPopupMenu 在屏幕的任意地方显示一个弹出式菜单 TrackPopupMenuEx 与TrackPopupMenu相似,只是它提供了额外的功能 作者Blog:http://blog.csdn.net/daiguopeng/ 相关文章 用VC 6.0实现串行通信的三种方法 windows运行命令详解 Windows API函数大全四 Windows API函数大全三 Windows API函数大全二

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧