zoukankan      html  css  js  c++  java
  • 窗体皮肤实现

    第一个实现了基本处理。窗体边框的宽度有些肥大,需要进行瘦身。

    实现:

        1、改变外框线宽度 (WM_NCCALCSIZE

        2、改变外框样式 (WM_WINDOWPOSCHANGING

    通过 WM_NCCALCSIZE 消息可以实现目的。

    procedure WMNCCalcSize(var message: TWMNCCalcSize); message WM_NCCALCSIZE;
    
    procedure TTest.WMNCCalcSize(var message: TWMNCCalcSize);
    const
      SIZE_BORDER = 5;
      SIZE_CAPTION = 28;
    begin
      // 改变边框尺寸
      with TWMNCCALCSIZE(Message).CalcSize_Params^.rgrc[0] do
      begin
        Inc(Left, SIZE_BORDER);
        Inc(Top, SIZE_CAPTION);
        Dec(Right, SIZE_BORDER);
        Dec(Bottom, SIZE_BORDER);
      end;
      Message.Result := 0;
      Handled := True;
    end;

    窗体的四个角的表现样式可以看出是XP的界面轮廓。倒角的幅度感觉有些大改小些。

    调整外框样式需要在窗体改变尺寸时进行处理,这种方法还可以实现不规则窗体。

    WM_WINDOWPOSCHANGING 这个消息可以满足需要。

    处理是需要注意的问题:

      1、因为是在调整过程中实际窗体的尺寸是无法通过 GetWindowRect 这个函数获取调整后的状态,因此需要保存有这个消息产生的窗体调整尺寸信息。

      2、这个消息会有很多模式,这个消息的触发来源 SetWindowPos 可以设置很多参数。我们只要处理窗体改变大小的模式,其他需要交由系统默认处理。

    调用控件默认消息处理

    procedure TTest.CallDefaultProc(var message: TMessage);
    begin
      ///
      ///  调用控件默认消息处理过错
      ///    为防止出现循环调用,需要使用状态控制(FCallDefaultProc)
      ///
      if FCallDefaultProc then
        FControl.WindowProc(message)
      else
      begin
        FCallDefaultProc := True;
        FControl.WindowProc(message);
        FCallDefaultProc := False;
      end;
    end;

    记录窗体位置和尺寸,并对窗体进行调整外框样式

    procedure TTest.WMWindowPosChanging(var Message: TWMWindowPosChanging);
    var
      bChanged: Boolean;
    begin
      /// 由外部优先处理消息,完成以下默认的控制
      CallDefaultProc(TMessage(Message));
    
      Handled := True;
      bChanged := False;
    
      /// 防止嵌套
      if FChangeSizeCalled then
        Exit;
    
      /// 调整窗体外框
      ///   如果窗体尺寸有调整时需要重新生成窗体外框区域。
      ///
      if (Message.WindowPos^.flags and SWP_NOSIZE = 0) or
         (Message.WindowPos^.flags and SWP_NOMOVE = 0) then
      begin
        if (Message.WindowPos^.flags and SWP_NOMOVE = 0) then
        begin
          FLeft := Message.WindowPos^.x;
          FTop := Message.WindowPos^.y;
        end;
        if (Message.WindowPos^.flags and SWP_NOSIZE = 0) then
        begin
          bChanged := ((Message.WindowPos^.cx <> FWidth) or (Message.WindowPos^.cy <> FHeight)) and
                     (Message.WindowPos^.flags and SWP_NOSIZE = 0);
          FWidth := Message.WindowPos^.cx;
          FHeight := Message.WindowPos^.cy;
        end;
      end;
    
      if (Message.WindowPos^.flags and SWP_FRAMECHANGED  <> 0) then
        bChanged := True;
    
      // 进行调整和重绘处理
      if bChanged then
      begin
        ChangeSize;
        InvalidateNC;
      end;
    end;

    调整窗体样式 

     1 procedure TTest.ChangeSize;
     2 var
     3   hTmp: HRGN;
     4 begin
     5   /// 调整窗体样式
     6   FChangeSizeCalled := True;
     7   try
     8     hTmp := FRegion;
     9     try
    10       /// 创建 倒角为3的矩形区域。
    11       ///    在这里可以实现不规则界面的创建,可以通过bmp创建绘制区域
    12       ///
    13       ///  注:
    14       ///    HRGN 句柄是是图形对象,由window管理的资源,不释放会出现内存泄露,
    15       ///    后果,你懂得。
    16       FRegion := CreateRoundRectRgn(0, 0, FWidth, FHeight, 3, 3);
    17       SetWindowRgn(Handle, FRegion, True);
    18     finally
    19       if hTmp <> 0 then
    20         DeleteObject(hTmp); // 释放资源
    21    end;
    22   finally
    23     FChangeSizeCalled := False;
    24   end;
    25 end;

    调整后的最终效果,瘦身感觉不错还算精致。

    代码下载: TestCaptionToolbar(v0.2).7z   

        http://pan.baidu.com/s/1jG64aFW

        https://github.com/cmacro/simple

    蘑菇房 (moguf.com)

  • 相关阅读:
    luoguP3822 [NOI2017]整数
    luoguP2150 [NOI2015]寿司晚宴
    luoguP3868 [TJOI2009]猜数字
    luoguP4777 【模板】扩展中国剩余定理(EXCRT)
    luoguP2048 超级钢琴
    题解 P1004 【方格取数】
    戊戌年西安游记
    题解 P4388 【付公主的矩形】
    题解 P4277 【河城荷取的烟花】
    001 dynamic Linq
  • 原文地址:https://www.cnblogs.com/gleam/p/3958944.html
Copyright © 2011-2022 走看看