窗口类设置背景为灰色运行时却显示白色

梦之领域 2013-03-04 12:42:42
C++ SDK 实现的一个简单的文字编辑器。为什么窗口类设置的灰色背景运行时显示的是白色背景?

// 简单的文字编辑器,按下 Escape 键、缩放窗口、改变键盘输入语言时都会清除窗口的内容。

#include<windows.h>

// 返回坐标 x,y 处字符引用
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)


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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Typer") ;

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 (GRAY_BRUSH) ;// 灰色背景
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;


if (!RegisterClass (&wndclass))
{
MessageBox ( NULL, TEXT ("程序请求 Windows NT!"), szAppName, MB_ICONERROR) ;
return 0 ;
}

hwnd = CreateWindow (szAppName,
TEXT ("打字程序"),
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 ;
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static DWORD dwCharSet = DEFAULT_CHARSET ; // 默认字符集

// 字符尺寸及客户区尺寸
static int cxChar, cyChar, cxClient, cyClient,
// 以字符为单位的x,y坐标及插入符坐标
cxBuffer, cyBuffer, xCaret, yCaret ;

static TCHAR *pBuffer = NULL ; // 字符缓冲区


HDC hdc ;
int x, y, i ;
PAINTSTRUCT ps ;
TEXTMETRIC tm ;


switch (message)
{
// 更改字符集
case WM_INPUTLANGCHANGE:// 改变键盘布局发送此消息
dwCharSet = wParam ;

// 失败


// 得到单个字符尺寸
case WM_CREATE:
hdc = GetDC (hwnd) ;

// CreateFont 第 9 个参数设为字符集ID,第 13 个参数设定为 FIXED_PITCH
SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;

GetTextMetrics (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cyChar = tm.tmHeight ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
ReleaseDC (hwnd, hdc) ;

// 失败



case WM_SIZE:

// 得到窗口尺寸(以像素为单位)

if (message == WM_SIZE)
{
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
}

// 计算窗口尺寸(以字符为单位)

cxBuffer = max (1, cxClient / cxChar) ;
cyBuffer = max (1, cyClient / cyChar) ;

// 为缓冲区分配内存

if (pBuffer != NULL) // 释放先前的内存
free (pBuffer) ;

// 分配能容纳当前窗口最大数量字符的内存
pBuffer = (TCHAR *) malloc (cxBuffer * cyBuffer * sizeof (TCHAR)) ;

// 初始为空字符
for (y = 0 ; y < cyBuffer ; y++)
for (x = 0 ; x < cxBuffer ; x++)
BUFFER(x,y) = ' ' ;

// 设置插入符到左上角

xCaret = 0 ;
yCaret = 0 ;

if (hwnd == GetFocus ()) // 窗口得到焦点

// 定位插入符到左上角( 0, 0 )
SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;

InvalidateRect (hwnd, NULL, TRUE) ;// 清空内容,发送 WM_PAINT 消息
return 0 ;


case WM_SETFOCUS: // 设置焦点

// 创建并显示插入符

CreateCaret (hwnd, NULL, cxChar, cyChar) ;
SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
ShowCaret (hwnd) ;
return 0 ;

case WM_KILLFOCUS:

// 隐藏并销毁插入符

HideCaret (hwnd) ;
DestroyCaret () ;
return 0 ;

case WM_KEYDOWN: // 键盘消息
switch (wParam)
{
case VK_HOME:
xCaret = 0 ;
break ;

case VK_END:
xCaret = cxBuffer - 1 ;
break ;

case VK_PRIOR:
yCaret = 0 ;
break ;

case VK_NEXT:
yCaret = cyBuffer - 1 ;
break ;

case VK_LEFT:
xCaret = max (xCaret - 1, 0) ;
break ;

case VK_RIGHT:
xCaret = min (xCaret + 1, cxBuffer - 1) ;
break ;

case VK_UP:
yCaret = max (yCaret - 1, 0) ;
break ;

case VK_DOWN:
yCaret = min (yCaret + 1, cyBuffer - 1) ;
break ;

case VK_DELETE:
// 该行字符自光标处起到最末的所有字符均前移一个
for (x = xCaret ; x < cxBuffer - 1 ; x++)
BUFFER (x, yCaret) = BUFFER (x + 1, yCaret) ;

// 清除方该行最后一个字符(此时它与前一个字符相同)
BUFFER (cxBuffer - 1, yCaret) = ' ' ;
//隐藏光标
HideCaret (hwnd) ;
hdc = GetDC (hwnd) ;
// 将等宽字体选入设备内容
SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
/*dwCharSet*/0, 0, 0, 0,FIXED_PITCH, NULL)) ;

// 重新输出删除后的文字,cxBuffer - xCaret 全字串长度 - 起始位 = 字串长度
TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
& BUFFER (xCaret, yCaret),
cxBuffer - xCaret) ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
ReleaseDC (hwnd, hdc) ;
// 恢复光标
ShowCaret (hwnd) ;
break ;
}

SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
return 0 ;

case WM_CHAR:
for (i = 0 ; i < (int) LOWORD (lParam) ; i++) // lParam 低字节为重复计数
{
switch (wParam) // 由 wParam 参数获得字符代码
{
case '\b': // 退格键 backspace
if (xCaret > 0)
{
xCaret-- ;
SendMessage (hwnd, WM_KEYDOWN, VK_DELETE, 1) ;
}
break ;

case '\t': // tab 键
do
{
// 先执行再判断是否 8 的倍数,因此总能执行
SendMessage (hwnd, WM_CHAR, ' ', 1) ;
} while (xCaret % 8 != 0) ;
break ;

case '\n': // 换行
if (++yCaret == cyBuffer)// 如果一行满,则回到左边
yCaret = 0 ;
break ;

case '\r': // 回车
xCaret = 0 ;

if (++yCaret == cyBuffer) // 如果一屏满,则跳到首行
yCaret = 0 ;
break ;

case '\x1B': // Esc键,清空文本
for (y = 0 ; y < cyBuffer ; y++)
for (x = 0 ; x < cxBuffer ; x++)
BUFFER (x, y) = ' ' ;

xCaret = 0 ;
yCaret = 0 ;

InvalidateRect (hwnd, NULL, FALSE) ;
break ;

// 字符代码(上面是控制代码)
default:
// 得到字符代码
BUFFER (xCaret, yCaret) = (TCHAR) wParam ;
HideCaret (hwnd) ;
hdc = GetDC (hwnd) ;

// 创建逻辑字体
SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;

// 输出该字符
TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
&BUFFER (xCaret, yCaret), 1) ;

DeleteObject ( SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
ReleaseDC (hwnd, hdc) ;
ShowCaret (hwnd) ;

if (++xCaret == cxBuffer) // 如果一行满,换行
{
xCaret = 0 ;
if (++yCaret == cyBuffer) // 如果一屏满,则跳到首行
yCaret = 0 ;
}
break ;
}
}
// 重置光标位置
SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
return 0 ;

case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;

SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;

// 输出所有字符
for (y = 0 ; y < cyBuffer ; y++)
TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
EndPaint (hwnd, &ps) ;
return 0 ;


case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}


请大神指教。
...全文
443 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Eleven 2013-03-05
  • 打赏
  • 举报
回复
设置背景透明,SetBkMode(TRANSPARENT)
jimette 2013-03-05
  • 打赏
  • 举报
回复
#define TRANSPARENT 1
梦之领域 2013-03-05
  • 打赏
  • 举报
回复
引用 3 楼 sha_jinhao 的回复:
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0, ……
代码改成这样,背景是有了(我还是没弄明白原来的代码为啥加了个字体到设备内容就没法显示有色背景了),但字符后面还有白色的背景,怎么去掉?
 case   WM_PAINT:
           hdc = BeginPaint (hwnd, &ps) ;

		   SetBkColor(hdc,RGB(100,100,100));
		   SetBkMode(hdc,0); // 设置字符显示为透明模式
		   
     
           SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
                                          dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;
        
	 	   // 输出所有字符
           for (y = 0 ; y < cyBuffer ; y++)
                TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;
        
           DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
           EndPaint (hwnd, &ps) ;
           return 0 ;
梦之领域 2013-03-05
  • 打赏
  • 举报
回复
引用 3 楼 sha_jinhao 的回复:
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0, ……
注释后变了,这是什么原因?问题是现存我需要用个有色的背景,这应该怎么做呢?
jimette 2013-03-04
  • 打赏
  • 举报
回复
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ; // 输出所有字符 for (y = 0 ; y < cyBuffer ; y++) TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ; DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ; EndPaint (hwnd, &ps) ; return 0 ; 把这段代码注释掉 看看变不变色!
信阳毛尖 2013-03-04
  • 打赏
  • 举报
回复
你的paint中哪里设置背景了?

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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