Thema: Delphi Menu Hintergrundbild

Einzelnen Beitrag anzeigen

EWeiss
(Gast)

n/a Beiträge
 
#9

AW: Menu Hintergrundbild

  Alt 31. Aug 2016, 15:18
Die Anzahl der NonVCL-Entwickler geht leider zurück. Umso genialer finde ich es, daß Du erstens weitermachst, und zweitens hier Deine Fortschritte und beeindruckenden Ergebnisse postest.

Sherlock
Danke ... Kann ich gebrauchen.

Hier nochmal alle benötigten Parts falls es mal jemand braucht. (In der Reihenfolge wie sie ausgeführt werden)
Die GDI+ Sachen muss man dann halt dementsprechend umlegen.
Jo ist was viel Aber was soll's.

PopupMenu erstellen.
Delphi-Quellcode:
{$REGION 'WM_NCRBUTTONDOWN'}
    WM_NCRBUTTONDOWN:
      begin
        hPopupMenu := CreatePopupMenu; // Bitmap Popupmenu
        hSubSkinMenu := CreatePopupMenu; // Bitmap SkinSubmenu
        if hPopupMenu <> 0 then
        begin
          AppendMenu(hPopupMenu, MF_OWNERDRAW, IDM_About, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW or MF_SEPARATOR, IDM_SeperatorSkins, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW or MF_POPUP, hSubSkinMenu, 'Skins');

          MnuSkins := nil;
          Files := nil;
          FindAllFiles(ExtractFilePath(ParamStr(0)) + 'Skins', '.ske', TRUE);
          SetLength(MnuSkins, Length(Files));

          if Assigned(SkinList) then
            SkinList.Clear;
          for IntI := 0 to Length(Files) - 1 do
          begin
            if not Assigned(SkinList) then
              SkinList := TStringList.Create;
            sSkinItem := Split(ExtractFileDir(Files[IntI]), '\');
            Item := High(sSkinItem);
            SkinList.Add(sSkinItem[Item]);
            AppendMenu(hSubSkinMenu, MF_OWNERDRAW, IDM_SKINS + IntI, '');
          end;

          AppendMenu(hPopupMenu, MF_OWNERDRAW or MF_SEPARATOR, IDM_SeperatorFiles, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW, IDM_AddFile, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW, IDM_AddFolder, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW or MF_SEPARATOR, IDM_SeperatorPList, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW, IDM_Playlist, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW or MF_SEPARATOR, IDM_SeperatorClose, '');
          AppendMenu(hPopupMenu, MF_OWNERDRAW, IDM_Close, '');

          GetCursorPos(p);
          MenuWahl := TrackPopupMenuEx(hPopupMenu, TPM_RETURNCMD, p.x, p.y, WinHandle, nil);
          DestroyMenu(hPopupMenu);
          ImgBack := 0;
          if MenuWahl then
            SendMessage(WinHandle, WM_COMMAND, Makelong(word(MenuWahl), 0), 0);
        end;
      end;
{$ENDREGION}
Delphi-Quellcode:
{$REGION 'WM_MEASUREITEM'}
    WM_MEASUREITEM:
      begin
        PMis := Pointer(lP);
        case PDis^.CtlType of
          ODT_MENU: // 1 Ownerdrawn menu
            begin
              if wP = 0 then
              begin
                Txt := WideString(GetMenuTxt(PDis.ItemId, Img, ImgItem, ImgSep));
                try
                  hFDefault := TFont.Create(PDis.hDC);
                  hFDefault.Name := SKAERO_TEXTFONT;
                  hFDefault.Size := SKAERO_PUSHBUTFONTSIZE;
                  PMis^.itemWidth := GetTextWidth(hFDefault, Txt) + 20;
                  PMis^.itemHeight := 20;
                  ImgItemHeight := PMis^.itemHeight;
                finally
                  hFDefault.Free;
                end;
                Result := 1;
                exit;
              end;
            end;
          ODT_LISTBOX:
            begin
              Result := 1;
              exit;
            end;
        end;
      end;
{$ENDREGION}
Delphi-Quellcode:
{$REGION 'WM_DRAWITEM'}
    WM_DRAWITEM:
      begin
        PDis := Pointer(lP);
        case PDis^.CtlType of
          ODT_MENU: // 1 Ownerdrawn menu
            begin
              hMenuWnd := WindowFromDC(PDis.HDC);

              if (IsWindow(hMenuWnd)) then
              begin
                if OnTransMenu then
                begin
                  if ckAeroBlur.GetCheckButtonStatus(ckAeroBlur.Handle)
                    or ckCrystal.GetCheckButtonStatus(ckCrystal.Handle) then
                    if trbGlassOpacity.GetTrackValue(trbGlassOpacity.Handle) >= 128 then
                      SKAERO_SetLayeredAlpha
                        (hMenuWnd, trbGlassOpacity.GetTrackValue(trbGlassOpacity.Handle))
                    else
                      SKAERO_SetLayeredAlpha(hMenuWnd, 128);
                end
                else
                  SKAERO_SetLayeredAlpha(hMenuWnd, 255)
              end;

              if hSubSkinMenu = PDis.ItemId then
                PDis.ItemId := IDM_Skin;

              GDIP_DisposeImage(Img);
              GDIP_DisposeImage(ImgItem);

              SetBkMode(PDis.HDC, OPAQUE);

              Txt := PWideChar(GetMenuTxt(PDis.ItemId, Img, ImgItem, ImgSep));

              // Create Graphics
              if GDIP_CreateFromHDC(PDis.HDC, Graphics) = 0 then
              begin
                // DrawButton
                if (PDis.itemState and ODS_SELECTED) <> 0 then
                  SKAERO_PaintButton(Graphics, 3, ImgItem, 20, PDis.rcItem.Top,
                    PDis.rcItem.Right, ImgItemHeight, BS_PUSHBUTTON)
                else
                begin
                  ImgBack := Cardinal(SKAERO_GetProperty(WinHandle, FORM_Center));

                  GetClientRect(hMenuWnd, Rect);
                  GDIP_GetImageSize(ImgBack, imgW, imgH);
                  GDIP_SetInterpolationMode(Graphics, InterpolationModeHighQualityBicubic);

                  GDIP_DrawImageRectRectI(Graphics, ImgBack, 20, PDis.rcItem.Top,
                    Rect.Right, ImgItemHeight, 0, PDis.rcItem.Top * (integer(imgH) div Rect.Bottom),
                      imgW, (integer(imgH) div Rect.Bottom) * ImgItemHeight, 2, nil, False, nil);

                  if (PDis.ItemId = IDM_SeperatorFiles) or (PDis.ItemId = IDM_SeperatorPList)
                    or (PDis.ItemId = IDM_SeperatorSkins) or
                    (PDis.ItemId = IDM_SeperatorClose) then

                  SKAERO_PaintButton(Graphics, 4, ImgItem, 20, PDis.rcItem.Top,
                    PDis.rcItem.Right, ImgItemHeight, BS_PUSHBUTTON)
                end;

                // DrawText
                GDIP_GetImageSize(Img, imgW, imgH);
                if not(PDis.ItemId = IDM_SeperatorFiles) and not(PDis.ItemId = IDM_SeperatorPList)
                  and not(PDis.ItemId = IDM_SeperatorSkins) and not
                  (PDis.ItemId = IDM_SeperatorClose) then
                begin
                  PDis.rcItem.Left := 38;
                  PDis.rcItem.Top := PDis.rcItem.Top + 2;
                  GDIP_DrawTextToDC(PDis.HDC, Txt, PDis.rcItem, SKAERO_INACTIVECAPTION, PWideChar
                    (SKAERO_TEXTFONT), SKAERO_PUSHBUTFONTSIZE, FontStyleBoldItalic, 1.1, 0);
                end
                else
                begin
                  // Allign Text Center
                  hFDefault := TFont.Create(PDis.hDC);
                  TxtLen := GetTextWidth(hFDefault, Txt);
                  PDis.rcItem.Left := ((PDis.rcItem.Right - TxtLen) div 2) - 6;
                  PDis.rcItem.Top := PDis.rcItem.Top;

                  GDIP_DrawTextToDC(PDis.HDC, Txt, PDis.rcItem, SKAERO_ACTIVECAPTION, PWideChar
                      (SKAERO_TEXTFONT), 13, FontStyleBold, 1.1, 0);
                  hFDefault.Free;
                end;

                PDis.rcItem.Left := 0;

                case PDis.ItemId of
                  IDM_WMPPRESET .. IDM_WMPPRESET_LAST:
                    begin
                      newItem := WMPVisPreset[PlgSelectedPreset];
                      if Txt = newItem then
                      begin
                        imgW := imgW div 2;
                        GDIP_DrawImageRectRectI
                          (Graphics, Img, PDis.rcItem.Left + 23, PDis.rcItem.Top + 2, imgW, imgH,
                          imgW, 0, imgW, imgH, 2, nil, False, nil);

                        GDIP_DisposeImage(Img);
                      end
                      else
                      begin
                        if (PDis.ItemId >= IDM_WMPPRESET) and (PDis.ItemId <= IDM_WMPPRESET_LAST)
                          then
                          imgW := imgW div 2;
                        GDIP_DrawImageRectRectI
                          (Graphics, Img, PDis.rcItem.Left + 23, PDis.rcItem.Top + 2, imgW, imgH, 0,
                          0, imgW, imgH, 2, nil, False, nil);

                        GDIP_DisposeImage(Img);
                      end;
                    end;
                  IDM_AMPMODULE .. IDM_AMPMODULE_LAST:
                    begin
                      newItem := AmpVisPreset[PlgSelectedModule];
                      if Txt = newItem then
                      begin
                        imgW := imgW div 2;
                        GDIP_DrawImageRectRectI
                          (Graphics, Img, PDis.rcItem.Left + 23, PDis.rcItem.Top + 2, imgW, imgH,
                          imgW, 0, imgW, imgH, 2, nil, False, nil);

                        GDIP_DisposeImage(Img);
                      end
                      else
                      begin
                        if (PDis.ItemId >= IDM_AMPMODULE) and (PDis.ItemId <= IDM_AMPMODULE_LAST)
                          then
                          imgW := imgW div 2;
                        GDIP_DrawImageRectRectI
                          (Graphics, Img, PDis.rcItem.Left + 23, PDis.rcItem.Top + 2, imgW, imgH, 0,
                          0, imgW, imgH, 2, nil, False, nil);

                        GDIP_DisposeImage(Img);
                      end;
                    end;
                  IDM_SKINS .. IDM_SKINS_LAST:
                    begin
                      newItem := SkinList[ActiveSkin];
                      if Txt = newItem then
                      begin
                        imgW := imgW div 2;
                        GDIP_DrawImageRectRectI
                          (Graphics, Img, PDis.rcItem.Left + 23, PDis.rcItem.Top + 2, imgW, imgH,
                          imgW, 0, imgW, imgH, 2, nil, False, nil);

                        GDIP_DisposeImage(Img);
                      end
                      else
                      begin
                        if (PDis.ItemId >= IDM_SKINS) and (PDis.ItemId <= IDM_SKINS_LAST) then
                          imgW := imgW div 2;
                        GDIP_DrawImageRectRectI
                          (Graphics, Img, PDis.rcItem.Left + 23, PDis.rcItem.Top + 2, imgW, imgH, 0,
                          0, imgW, imgH, 2, nil, False, nil);

                        GDIP_DisposeImage(Img);
                      end;
                      PDis.rcItem.Left := 0;
                    end;
                else
                  begin
                    GDIP_GetImageSize(Img, imgW, imgH);
                    GDIP_DrawImageRectRectI(Graphics, Img, 23, PDis.rcItem.Top,
                      imgW, imgH, 0, 0, imgW, imgH, 2, nil, False, nil);
                  end;
                end;

                if (PDis.itemAction and ODA_DRAWENTIRE) <> 0 then
                begin
                  GetClipBox(PDis.hDC, Rect);
                  GDIP_FillRect(Graphics, 0, 0, 20, Rect.Bottom, SKAERO_INACTIVECAPTION);

                  if Rect.Bottom > 100 then
                  begin
                    hFDefault := TFont.Create(PDis.hDC);
                    hFDefault.Name := SKAERO_TEXTFONT;
                    hFDefault.Size := 10;
                    hFDefault.Style := [fsBold, fsUnderline];
                    hFDefault.Orientation := 900;
                    hFDefault.Color := RGB(255,255,250);
                    Rect.Bottom := Rect.Bottom + 12;
                    DrawText(PDis.hDC, 'Sound Machine', length('Sound Machine'), Rect,
                      DT_BOTTOM or DT_LEFT or DT_SINGLELINE);

                    hFDefault.Free;
                  end;
                end;
                GDIP_DeleteGraphics(Graphics);
              end;
              Result := 1;
              exit;
            end;
          ODT_LISTBOX:
            begin
              Result := 1;
              exit;
            end;
        end;
      end;
{$ENDREGION}
Delphi-Quellcode:
{$REGION 'function GetMenuTxt'}

// Hier wird der Text für den Menu Eintrag übergeben
// und für diesen Eintrag zugehörige icon als *.png File 16x16
function GetMenuTxt(ItemId: integer; var Img: Cardinal; var ImgItem: Cardinal;
  var ImgSep: Cardinal): WideString;
var
  sItem: string;
  hList: HWND;

begin

  case ItemId of
    IDM_SeperatorClose:
      Result := '-Application-';
    IDM_Close:
    begin
      sItem := 'Menu\MEN_Close.png';
      Result := 'Close SoundMachine';
    end;
    IDM_About:
    begin
      sItem := 'Menu\MEN_About.png';
      Result := 'About';
    end;
    IDM_WMPPRESET .. IDM_WMPPRESET_LAST:
    begin
      sItem := 'BTN_Check.png';
      Result := WMPVisPreset[ItemId - IDM_WMPPRESET];
    end;
    IDM_AMPMODULE .. IDM_AMPMODULE_LAST:
    begin
      sItem := 'BTN_Check.png';
      Result := AmpVisPreset[ItemId - IDM_AMPMODULE];
    end;
    IDM_SeperatorSkins:
      Result := '-Appearance-';
    IDM_Skin:
    begin
      sItem := 'Menu\MEN_SkinFolder.png';
      Result := 'Skins';
    end;
    IDM_SKINS .. IDM_SKINS_LAST:
    begin
      sItem := 'BTN_Check.png';
      Result := SkinList[ItemId - IDM_SKINS];
    end;
    IDM_SeperatorFiles:
      Result := '-File Dependencies-';
    IDM_AddFile:
    begin
      sItem := 'Menu\MEN_File.png';
      Result := 'Add File';
    end;
    IDM_AddFolder:
    begin
      sItem := 'Menu\MEN_Folder.png';
      Result := 'Add Folder';
    end;
    IDM_SeperatorPList:
      Result := '-Playlist-';
    IDM_Playlist:
      begin
        sItem := 'Menu\MEN_Playlist.png';
        hList := SKAERO_GetMainItem(MainHandle, ID_PLAYLIST);
        if isWindowVisible(hList) then
          Result := 'Hide PlayList'
        else
          Result := 'Show PlayList';
      end;
  end;

  Img := SKAERO_AddResource(MainHandle, PWideChar(SKAERO_CONFIG_GetSkinFolder + sItem));
  if TmpImgItem = 0 then
    TmpImgItem := SKAERO_AddResource(MainHandle, PWideChar
        (SKAERO_CONFIG_GetSkinFolder + 'List\ListSelect.png'))
  else
    ImgItem := TmpImgItem;

  if TmpImgSep = 0 then
    TmpImgSep := SKAERO_AddResource(MainHandle, PWideChar
        (SKAERO_CONFIG_GetSkinFolder + 'Shape.png'))
  else
    ImgSep := TmpImgSep;
end;
{$ENDREGION}
Delphi-Quellcode:
function GetTextWidth(fnt: TFont; const text: string): Integer;
var
  dc: hdc;
  tsize: Windows.tsize;
begin
  dc := GetDC(0);
  SelectObject(dc, fnt.Handle);
  GetTextExtentPoint32(dc, PWideChar(text), Length(text), tsize);
  ReleaseDC(0, dc);
  Result := tsize.cx;
end;
gruss

Geändert von EWeiss (31. Aug 2016 um 15:53 Uhr)
  Mit Zitat antworten Zitat