修正XPMenu的两个Bug[3]

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 nhconch 的 blog


2、第二个问题是菜单的阴影太呆板,是固定的一层灰色块(当然是指winxp以前的系统),如图:
xpmenu菜单阴影问题修正前

  菜单阴影是由txpmenu.drawwindowborder函数绘制的。这里可以看到+jt进行过修改,不过+jt的注释方式有点特别,看不出那些在作者的原代码,那些是+jt改过的,不过可以肯定+jt下了不少苦功。这个函数把windows来的那个3d边框去掉,变成平面的officexp风格菜单。若果要改为像winxp菜单的那种通过与背景像素混合的得到的阴影效果,必须对源码进行大改,但使用第三方控件目的是为了方便省事,如果那样做的话就太有违初衷了。因此我这里用了一种折衷的办法,把灰色面积减少,这样看起来就顺眼多了。最终效果如下图:
xpmenu菜单阴影问题修正后
  修改后的txpmenu.drawwindowborder函数:

procedure txpmenu.drawwindowborder(hwnd: hwnd; isrighttoleft: boolean);
var
  wrect: trect;
  dcanvas: tcanvas;
  wdc: hdc; // +jt

 regiontype: integer; // +jt
 r1,r2,wr,region: hrgn; // +jt
 rgnr: trect; // +jt
begin

  if (hwnd <= 0) or (fsettingwindowrng) then
 begin
  exit;
 end;
// +jt
 wdc := getwindowdc(hwnd); //getdesktopwindow
 if wdc=0 then exit;
// +jt
  fsettingwindowrng :=true; // +jt
 dcanvas := tcanvas.create;
 try
   dcanvas.handle := wdc; // +jt
    getwindowrect(hwnd, wrect);
  // +jt
   wrect.right := wrect.right-wrect.left;
   wrect.bottom := wrect.bottom-wrect.top;
   wrect.top:=0;
   wrect.left:=0;
    if getwindowlong(hwnd,gwl_wndproc)<>integer(@menuwindowproc) then
   begin
     setwindowlong(hwnd,gwl_userdata,getwindowlong(hwnd,gwl_wndproc));
     setwindowlong(hwnd,gwl_wndproc,integer(@menuwindowproc));
   end;
{modify: conch 2004-11-04 画出的阴影太难看了
    if not iswxp then
   begin
      wr:= createrectrgn(0,0,0,0);
     regiontype := getwindowrgn(hwnd, wr);
     getrgnbox(wr,rgnr);
     deleteobject(wr);
      if (regiontype = error) or (abs(rgnr.right-wrect.right)>5) or (abs(rgnr.bottom-wrect.bottom)>5) then
     begin
       region:= createrectrgn(0,0,0,0);
       r1:=createrectrgn(wrect.left,wrect.top,wrect.right-2,wrect.bottom-2);
       r2:=createrectrgn(wrect.left+2,wrect.top+2,wrect.right,wrect.bottom);
       combinergn(region,r1,r2,rgn_or);
       deleteobject(r1);
       deleteobject(r2);
        setwindowrgn(hwnd,region,true);
      end;
 // +jt
      dec(wrect.right, 2);
     dec(wrect.bottom, 2);
   end; // +jt
}

    dcanvas.brush.style := bsclear;
    dcanvas.pen.color := fmenubordercolor;
   dcanvas.rectangle(wrect.left, wrect.top, wrect.right, wrect.bottom);
    if isrighttoleft then
   begin
      dcanvas.pen.color := fficonbackcolor;
     dcanvas.moveto(wrect.right - 3, wrect.top + 2);
     dcanvas.lineto(wrect.right - 2, wrect.bottom - 1);
    end
   else
   begin
     dcanvas.pen.color := fficonbackcolor;
     dcanvas.rectangle(wrect.left + 1, wrect.top + 2, wrect.left + 3, wrect.bottom - 1);
   end;
// +jt
       stretchblt(dcanvas.handle,wrect.left + 1,wrect.top + 1,wrect.right - wrect.left-1,2,
                  dcanvas.handle,wrect.left + 1,wrect.top + 3,wrect.right - wrect.left-1,1,srccopy);
        if iswxp then
       begin
         stretchblt(dcanvas.handle,wrect.left + 1,wrect.bottom - 3,wrect.right - wrect.left-1,2,
                    dcanvas.handle,wrect.left + 1,wrect.top + 3,wrect.right - wrect.left-1,1, srccopy);
         dcanvas.pen.color := ffcolor;
         dcanvas.rectangle(wrect.right - 3, wrect.top+1, wrect.right - 1, wrect.bottom-1);
       end;
// +jt
{modify: conch 2004-11-04 画出的阴影太难看了
    inc(wrect.right, 2);
   inc(wrect.bottom, 2);
    if not iswxp then // +jt
   begin // +jt
     dcanvas.pen.color := fmenushadowcolor;
     dcanvas.rectangle(wrect.left + 2, wrect.bottom, wrect.right, wrect.bottom - 2);
     dcanvas.rectangle(wrect.right - 2, wrect.bottom, wrect.right, wrect.top + 2);
   end; // +jt
}

 finally
   releasedc(hwnd, wdc); // +jt
   dcanvas.free;
 fsettingwindowrng :=false;
 end;

end;

本文关键:修正XPMenu的两个Bug
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top