首页
社区
课程
招聘
[求助]如何改变Button 的背景色?
发表于: 2008-11-20 10:55 6456

[求助]如何改变Button 的背景色?

2008-11-20 10:55
6456

征集方法.
除了使用OwnerDraw风格的按钮外,可不可以靠发送消息的办法来实现?

例如: 本来背景色是灰色的
收到初始化消息后,将其背景色设置为蓝色.

如何实现?


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
CodeProject上有你想要的.
2008-11-20 12:01
0
雪    币: 207
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
能给个链接吗?
搜索了一下,没找到.
2008-11-20 14:45
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
program RawGUI;

uses
  Windows,Messages;

var
  lpMsg:            TMsg;
  hwndMain:         HWND;
  hwndBtn:         HWND;
  wndClass:         TWndClass;
  OldBtnWndProc:    Pointer;

function GetWinText(AWin: Thandle): string;
var
  ResultStr: String;
begin
  SetLength(ResultStr, GetWindowTextLength(AWin));
  GetWindowText(AWin,@ResultStr[1],Length(ResultStr)+1);
  Result := ResultStr;
  ResultStr := '';
end;

function MessageFunc(hWnd, Msg, wParam, lParam: integer): integer; stdcall;
begin

  case Msg of
     $0111 :
     begin
        if ((wParam and $FFFF) = 1) then
        begin
           MessageBox(hwndMain,':)','xx',MB_OK);
        end;
     end;
     $0002 :  PostQuitMessage(0);
  end;
  result:=DefWindowProc(hWnd, Msg, wParam, lParam);
end;

procedure SetBtnMemDCText(memDC: HDC;Rect:TRect; AText: string);
var
  LFont: HFONT;
  _Bold,_UnderLine:bool;
  FontColor:Cardinal;
begin
  _Bold := false;
  _UnderLine := false;
  FontColor := $00CFCF;
  LFont := CreateFont(12, 0, 0, 0, FW_EXTRALIGHT, Byte(False), Byte(_UnderLine), Byte(false), GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, 'Fixedsys');
  SelectObject(memDC, LFont);
  SetTextColor(memDC, FontColor);
  SetBkMode(memDC, TRANSPARENT);
  DrawText(memDC, PChar(AText), Length(AText),Rect,DT_CENTER or DT_VCENTER or DT_SINGLELINE);
  DeleteObject(LFont);
end;

function NewBtnWndProc(hWin: HWND; uMsg: word; wParam: WPARAM;
  lParam: LPARAM):DWORD; stdcall;

var
  memDC:  HDC;
  Rect:   TRect;
  Pt:     TPoint;
  ps:     TPaintStruct;
  WndHdc: HDC;
begin
  case uMsg of
    WM_Paint, WM_ERASEBKGND, WM_CAPTURECHANGED, WM_SETFOCUS, WM_KILLFOCUS, WM_MOUSEACTIVATE:
    begin
      if uMsg = WM_PAINT then
        WndHdc := BeginPaint(hWin, ps);

      GetClientRect(hWin, rect);
      if not ((uMsg = WM_PAINT) or (uMsg = WM_ERASEBKGND)) then
        InvalidateRect(hWin, @rect, True);
      //边框   
      FillRect(wParam, rect, CreateSolidBrush($00FF0000));
      //背景
      InflateRect(Rect,-1,-1);
      FillRect(wParam, rect, CreateSolidBrush($0));
      //文字
      InflateRect(Rect,-1,-1);
      SetBtnMemDCText(wParam,Rect,GetWinText(hWin));

      Result := 1;
      if uMsg = WM_PAINT then
        EndPaint(hWin, ps);
      exit;
    end;
  end;
  Result := CallWindowProc(OldBtnWndProc, hWin, uMsg, wParam, lParam);
end;

procedure CreateUI;
begin

  FillChar(wndClass, SizeOf(wndClass), 0);

  wndClass.lpfnWndProc:=@MessageFunc;
  wndClass.hInstance:=SysInit.hInstance;
  wndClass.hCursor:=LoadCursor(0, IDC_ARROW);
  wndClass.hbrBackground:=COLOR_BTNFACE + 1;
  wndClass.lpszClassName:='FkMJ';

  RegisterClass(wndClass);

  hwndMain:=CreateWindow(wndClass.lpszClassName, 'PP Button', WS_SYSMENU or WS_VISIBLE, 100, 100, 80, 63, 0, 0, hInstance, nil);
  hwndBtn := CreateWindow('BUTTON', 'OK', BS_PUSHBUTTON or WS_VISIBLE or
    WS_CHILD, 28, 6, 43, 19, hwndMain, 1, hInstance, nil);
  SendMessage(hwndBtn, $0030, GetStockObject(ANSI_FIXED_FONT), 0);

  OldBtnWndProc := Pointer(SetWindowLong(hwndBtn, GWL_WNDPROC,
    longint(@NewBtnWndProc)));

  while GetMessage(lpMsg, 0, 0, 0) do
  begin
     TranslateMessage(lpMsg);
     DispatchMessage(lpMsg);
  end;

end;

begin
  CreateUI;
end.

东拼西凑,有了点效果,不知道是不是你想要的。
2008-11-20 23:49
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我很欣赏360的界面,以后准备模仿他的做一套出来。如果你有兴趣,一起努力吧。
上传的附件:
2008-11-20 23:54
0
雪    币: 207
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
哇.. 好长~`
我本以为,10来句代码就可以搞定的.

原来是要自绘啊..
2008-11-21 09:54
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感动,居然被加声望了,我得多努力啊,要不然对不起这点声望。
是自绘啊,就我所知button没有类似的属性可以设置,基本上就是自己画了。

那么长,是个完整的程序的代码啊,你所需要的也不过就是十几而是来句。另外,也许有什么简单的办法,还恳请各位UI高手指点。

PS:360的UI程序员如果来到这里,能不能密我下,我很想向你们请教啊。
2008-11-21 11:21
0
雪    币: 242
活跃值: (443)
能力值: ( LV11,RANK:188 )
在线值:
发帖
回帖
粉丝
8
win程序设计没看完,hmm

用SetSysColors来改变按钮的外观可能不是您想做的,这会影响目前在Windows下执行的所有程序,这也是使用者不太喜欢的。

更好的方法(同样也只是理论上)是处理WM_CTLCOLORBTN消息,这是当子窗口即将为其显示区域着色时,由按钮控件发送给其父窗口消息处理程序的一个消息。父窗口可以利用这个机会来改变子窗口消息处理程序将用来着色的颜色(在Windows的16位版本中,一个称为WM_CTLCOLOR的消息被用于所有的控件,现在针对每种型态的标准控件,分别代之以不同的消息)。

当父窗口消息处理程序收到WM_CTLCOLORBTN消息时,wParam消息参数是按钮的设备内容句柄,lParam是按钮的窗口句柄。当父窗口消息处理程序得到这个消息时,按钮控件已经获得了它的设备内容。当您的窗口消息处理程序处理一个WM_CTLCOLORBTN消息时,您必须完成以下三个动作:

使用SetTextColor选择设定一种文字颜色。
 
使用SetBkColor选择设定一种文字背景颜色。
 
将一个画刷句柄传回给子窗口。
 
理论上,子窗口使用该画刷来着色背景。当不再需要这个画刷时,您应该负责清除它。

下面是使用WM_CTLCOLORBTN的问题所在:只有按键和拥有者绘制按钮才给其父窗口发送WM_CTLCOLORBTN,而只有拥有者绘制按钮才会响应父窗口消息处理程序对消息的处理,而使用画刷来着色背景。这基本上是没有意义的,因为无论怎样都是由父窗口来负责绘制拥有者绘制按钮。
2008-11-21 15:19
0
游客
登录 | 注册 方可回帖
返回
//