Down个XPMenu控件,研究一下,有帮助的

解决方案 »

  1.   

    procedure TXPMenu.MenueDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
      Selected: Boolean);
    var
      txt: string;
      B: TBitmap;
      IconRect, TextRect, CheckedRect: TRect;
      i, X1, X2: integer;
      TextFormat: integer;
      HasImgLstBitmap: boolean;
      FMenuItem: TMenuItem;
      FMenu: TMenu;
      FTopMenu: boolean;
      ISLine: boolean;
      ImgListHandle: HImageList;        {Commctrl.pas}
      ImgIndex: integer;
      hWndM: HWND;
      hDcM: HDC;
    begin
      FTopMenu := false;
      FMenuItem := TMenuItem(Sender);  SetGlobalColor(ACanvas);  if FMenuItem.Caption = '-' then IsLine := true else IsLine := false;  FMenu := FMenuItem.Parent.GetParentMenu;  if FMenu is TMainMenu then
        for i := 0 to FMenuItem.GetParentMenu.Items.Count - 1 do
          if FMenuItem.GetParentMenu.Items[i] = FMenuItem then
          begin
            FTopMenu := True;
            break;
          end;
      ACanvas.Font.Assign(FFont);
      if FMenu.IsRightToLeft then
        ACanvas.Font.Charset := ARABIC_CHARSET;  Inc(ARect.Bottom, 1);
      TextRect := ARect;
      txt := ' ' + FMenuItem.Caption;  B := TBitmap.Create;  HasImgLstBitmap := false;
      if FMenuItem.Bitmap.Width > 0 then
        B.Assign(TBitmap(FMenuItem.Bitmap));  if (FMenuItem.Parent.GetParentMenu.Images <> nil)
      {$IFDEF VER5U}
      or (FMenuItem.Parent.SubMenuImages <> nil)
      {$ENDIF}
      then
      begin
        if FMenuItem.ImageIndex <> -1 then
          HasImgLstBitmap := true
        else
          HasImgLstBitmap := false;
      end;  if FMenu.IsRightToLeft then
      begin
        X1 := ARect.Right - FIconWidth;
        X2 := ARect.Right;
      end
      else
      begin
        X1 := ARect.Left;
        X2 := ARect.Left + FIconWidth;
      end;
      IconRect := Rect(X1, ARect.Top, X2, ARect.Bottom);
      if HasImgLstBitmap then
      begin
        CheckedRect := IconRect;
        Inc(CheckedRect.Left, 1);
        Inc(CheckedRect.Top, 2);
        Dec(CheckedRect.Right, 3);
        Dec(CheckedRect.Bottom, 2);  end
      else
      begin
        CheckedRect.Left := IconRect.Left +
          (IConRect.Right - IconRect.Left - 10) div 2;
        CheckedRect.Top := IconRect.Top +
          (IConRect.Bottom - IconRect.Top - 10) div 2;
        CheckedRect.Right := CheckedRect.Left + 10;
        CheckedRect.Bottom := CheckedRect.Top + 10;  end;
      if FMenu.IsRightToLeft then
      begin
        X1 := ARect.Left;
        X2 := ARect.Right - FIconWidth;
        if B.Width > FIconWidth then
          X2 := ARect.Right - B.Width - 4;
      end
      else
      begin
        X1 := ARect.Left + FIconWidth;
        if B.Width > X1 then
          X1 := B.Width + 4;
        X2 := ARect.Right;
      end;  TextRect := Rect(X1, ARect.Top, X2, ARect.Bottom);  if FTopMenu then
      begin
        if not HasImgLstBitmap then
        begin
          TextRect := ARect;
        end
        else
        begin
          if FMenu.IsRightToLeft then
            TextRect.Right := TextRect.Right + 5
          else
            TextRect.Left := TextRect.Left - 5;
        end  end;  if FTopMenu then
      begin
        ACanvas.brush.color := FFMenuBarColor;
        ACanvas.Pen.Color := FFMenuBarColor;    ACanvas.FillRect(ARect);
      end
      else
      begin
        if (Is16Bit and FGradient) then
        begin
          inc(ARect.Right,2);  //needed for RightToLeft
          DrawGradient(ACanvas, ARect, FMenu.IsRightToLeft);
          Dec(ARect.Right,2);    end
        else
        begin
          ACanvas.brush.color := FFColor;
          ACanvas.FillRect(ARect);      ACanvas.brush.color := FFIconBackColor;
          ACanvas.FillRect(IconRect);
        end;
    //------------
      end;
      if FMenuItem.Enabled then
        ACanvas.Font.Color := FFont.Color
      else
        ACanvas.Font.Color := FDisabledColor;  if Selected and FDrawSelect then
      begin
        ACanvas.brush.Style := bsSolid;
        if FTopMenu then
        begin
          DrawTopMenuItem(FMenuItem, ACanvas, ARect, FMenu.IsRightToLeft);
        end
        else
          //------
          if FMenuItem.Enabled then
          begin        Inc(ARect.Top, 1);
            Dec(ARect.Bottom, 1);
            if FFlatMenu then
              Dec(ARect.Right, 1);
            ACanvas.brush.color := FFSelectColor;
            ACanvas.FillRect(ARect);
            ACanvas.Pen.color := FFSelectBorderColor;
            ACanvas.Brush.Style := bsClear;
            ACanvas.RoundRect(Arect.Left, Arect.top, Arect.Right,
              Arect.Bottom, 0, 0);
            Dec(ARect.Top, 1);
            Inc(ARect.Bottom, 1);
            if FFlatMenu then
              Inc(ARect.Right, 1);
          end;
          //-----  end;  DrawCheckedItem(FMenuItem, Selected, HasImgLstBitmap, ACanvas, CheckedRect);//-----  if HasImgLstBitmap then
      begin
      {$IFDEF VER5U}
        if FMenuItem.Parent.SubMenuImages <> nil then
        begin
          ImgListHandle := FMenuItem.Parent.SubMenuImages.Handle;
          ImgIndex := FMenuItem.ImageIndex;      B.Width := FMenuItem.Parent.SubMenuImages.Width;
          B.Height := FMenuItem.Parent.SubMenuImages.Height;
          B.Canvas.Brush.Color := FFIconBackColor;
          B.Canvas.FillRect(Rect(0, 0, B.Width, B.Height));
          ImageList_DrawEx(ImgListHandle, ImgIndex,
            B.Canvas.Handle, 0, 0, 0, 0, clNone, clNone, ILD_Transparent);    end
        else
      {$ENDIF}
        begin
          ImgListHandle := FMenuItem.Parent.GetParentMenu.Images.Handle;
          ImgIndex := FMenuItem.ImageIndex;      B.Width := FMenuItem.Parent.GetParentMenu.Images.Width;
          B.Height := FMenuItem.Parent.GetParentMenu.Images.Height;
          B.Canvas.Brush.Color := FFIconBackColor;
          B.Canvas.FillRect(Rect(0, 0, B.Width, B.Height));
          ImageList_DrawEx(ImgListHandle, ImgIndex,
            B.Canvas.Handle, 0, 0, 0, 0, clNone, clNone, ILD_Transparent);    end;
      end  else
        if FMenuItem.Bitmap.Width > 0 then
          B.Assign(TBitmap(FMenuItem.Bitmap));
      DrawIcon(FMenuItem, ACanvas, B, IconRect,
        Selected, False, FMenuItem.Enabled, FMenuItem.Checked,
        FTopMenu, FMenu.IsRightToLeft);
    //--------
      if not IsLine then
      begin    if FMenu.IsRightToLeft then
        begin
          TextFormat := DT_RIGHT + DT_RTLREADING;
          Dec(TextRect.Right, 5);
        end
        else
        begin
          TextFormat := 0;
          Inc(TextRect.Left, 5);
        end;    DrawTheText(txt, ShortCutToText(FMenuItem.ShortCut),
          ACanvas, TextRect,
          Selected, FMenuItem.Enabled, FMenuItem.Default,
          FTopMenu, FMenu.IsRightToLeft, TextFormat);//-----------  end
      else
      begin
        if FMenu.IsRightToLeft then
        begin
          X1 := TextRect.Left;
          X2 := TextRect.Right - 7;
        end
        else
        begin
          X1 := TextRect.Left + 7;
          X2 := TextRect.Right;
        end;    ACanvas.Pen.Color := FFSeparatorColor;
        ACanvas.MoveTo(X1,
          TextRect.Top +
          Round((TextRect.Bottom - TextRect.Top) / 2));
        ACanvas.LineTo(X2,
          TextRect.Top +
          Round((TextRect.Bottom - TextRect.Top) / 2))
      end;  B.free;//------  if not (csDesigning in ComponentState) then
      begin
        if (FFlatMenu) and (not FTopMenu) then
        begin
          hDcM := ACanvas.Handle;
          hWndM := WindowFromDC(hDcM);
          if hWndM <> FForm.Handle then
          begin
            DrawWindowBorder(hWndM, FMenu.IsRightToLeft);
          end;
        end;
      end;//-----
      ActivateMenuItem(FMenuItem);  // to check for new sub items
    end;