Avatar billede hrc Mester
05. august 2008 - 13:08 Der er 10 kommentarer og
1 løsning

TMenuItem.Checked ses ikke når TPopupMenu.Images er sat

Jeg har et banalt problem med en popup menu. Bruger den som filtervælger og hver filtertype har sin egen ikon som jeg gerne vil vise i menuen.

Når de er koblet til menuen (vha. en TImageList), kan man ikke se om Checked-flaget er sat eller ej. Jeg kører Classic Windows interface og det er åbenbart kun der det forekommer. Den XP indstilling har jeg ikke tænkt at ændre på (har fjernet themes servicen).

Det er åbenbart et gammelt problem: http://qc.codegear.com/wc/qcmain.aspx?d=6895.

Hvordan kan jeg få ikoner og check-flag på mine TMenuItems?

Overvejer om jeg kan lave et overlay ikon (med et "check mark") som jeg lægger hen over filterets ikon. Alternativt kan jeg dublere ikonerne og lægge en "check mark"-ikon over det ene sæt.

Skal jeg over i OnOwnerDraw?
Avatar billede mbsnet Nybegynder
06. august 2008 - 05:36 #1
Hej Hrc, tror ikke du kan gøre begge dele samtidig, uden at tegne selv. Dette gælder jo også for TMainMenu. Alternativt kan du jo lave elementerne som sub-menuer, som så har de egenskaber med check-marks (altså til hvert emne).

//mbs
Avatar billede mbsnet Nybegynder
06. august 2008 - 05:37 #2
[MENU]
  [ELEMENT]
    [CHECK-ITEM 1]
    [CHECK-ITEM 2]
Avatar billede hrc Mester
06. august 2008 - 07:22 #3
Jeg kan godt se at pladsen mangler. Der er ikke 16 pixels til ikonen og 16 til checkboksen. Regner ikke med at checktegnet vil kunne ligge over grafikken (havde ellers været elegant)

  And now for something completly different...

Gik ind på din side og blev nødt til at kommentere (har bare ikke lyst til at registre) den IsNumeric (I Delphi delen) som en eller anden har lagt ind. Den kunne være pænere (formateret korrekt):

function isNumeric(theStr: string): boolean;
var
  i: integer;
  ch: byte;
begin
  result := true;
  i := 0;
  if theStr = '' then
    result := false
  else
    while i < length(theStr) do
    begin
      inc(i);
      ch := ord(theStr[i]);
      if (ch < 48) or (ch > 57) then
      begin
        result := false;
        exit;
      end;
    end;
end;

... er en noget kluntet fremgangsmåde. Denne synes jeg er pænere:

function IsNumeric(const aString: string): boolean;
var
  i: integer;
  Lgd: integer;
begin
  Lgd := length(aString); // Burde der trimmes først?
  result := Lgd > 0; i := 0;
  while (i < Lgd) and result do
  begin
    inc(i);
    result := aString[i] in ['0'..'9'];
  end;
end;

... skal der tjekkes for negative og decimaltal bliver den lidt udbygget:

function IsNumeric(const aString: string): boolean;
var
  ch: char;
  i: integer;
  Lgd: integer;
  MinusCount: integer;
  DecimalSeparatorCount: integer;
begin
  MinusCount := 0;
  DecimalSeparatorCount := 0;
  Lgd := length(aString); // Burde der trimmes først?
  result := Lgd > 0; i := 0;
  while (i < Lgd) and result do
  begin
    inc(i);
    ch := aString[i];
    result := ch in ['0'..'9',DecimalSeparator,'-'];
    inc(MinusCount,integer(ch = '-'));
    inc(DecimalSeparatorCount,integer(ch = DecimalSeparator));
  end;
  if result then
    result := ((MinusCount = 0) or (aString[1] = '-'))
          and (DecimalSeparatorCount in [0,1]);
end;

Endelig må jeg erkende at der allerede er en funktion der klarer alt dette: Math.IsNAN :-)
Avatar billede mbsnet Nybegynder
06. august 2008 - 09:06 #4
Hej, alt hvad der ligger på min side er gammelt materiale. Er blevet noget bedre i mellemtiden. Takket være dig bla.. :) Jeg er ved at lave en server i Delphi, og når den bliver klar, opdaterer jeg indholdet af hjemmesiden.

Mht til menuerne, synes jeg også engang at have set en "down" propery, men har ikke lige kunne finde den i main/popup p.t.
Avatar billede mbsnet Nybegynder
06. august 2008 - 09:14 #5
Det med isnumeric gør jeg nu således:

function isBetween(const i,a,b:str):boolean;    //bruger overload for int mm.
begin result:=(i>=a) and (i<=b) end;

function isNumericChar(const ch:sChar):boolean; 
begin result:=isBetween(ch,'0','9') end;

function isNumeric(const s:str):boolean;
var i:smallInt;
begin clr(result);if empty(s) then exit;
for i:=1 to length(s) do if not isNumericChar(s[i]) then exit;result:=true
end;
Avatar billede mbsnet Nybegynder
06. august 2008 - 09:15 #6
og sChar er:

type
sChar=string[1];
Avatar billede mbsnet Nybegynder
07. august 2008 - 10:07 #7
Lgd := length(aString); // Burde der trimmes først?

Der bør ikke trimmes her, fordi lgd er en "intern" variabel af funktionen, og vil afgøre funktionens resultat her udfra. Hvis resultatet er TRUE baseret på det trim, vil man møde en intToStr konverteringsfejl bagefter..

Ved godt at min "nye" måde at bruge isNumeric, stadig ikke klarer decimaltal og tal mindre end nul, men hvis man kun bruger til funktionen til heltal over nul, er det stadig en ret hurtig måde at gøre det på. De få gange jeg har haft behov for at bruge funktionen i forbindelse med de andre typer tal, har jeg benyttet replaceChar (hjemmelavet) og removeLeading(DASH) / removeTrailing (også hjemmelavet)

mvh mbs
Avatar billede mbsnet Nybegynder
07. august 2008 - 10:10 #8
p.s. hjemmelavet fordi jeg først opdagede lang tid senere at der ligger nogle sammen med indy som kan det samme, men de hjemmelavede har kørt godt nok til at de er beholdt
Avatar billede hrc Mester
10. september 2008 - 09:49 #9
mbsnet: Vil du have points som tak for hjælpen?
Avatar billede mbsnet Nybegynder
10. september 2008 - 20:27 #10
Nej tak, håber at kunne hjælpe bedre en anden gang.
Avatar billede hrc Mester
10. september 2008 - 21:35 #11
OK. Jeg lukker nu.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester