Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Delphi] EM_SETMARGINS op een TCustomEdit

Pagina: 1
Acties:
  • 290 views sinds 30-01-2008
  • Reageer

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Ik probeer een TCustomEdit descendant te maken die aan de rechterkant een knopje weergeeft. Op internet zijn er al enkele controls die dat doen, maar ze hebben allemaal een probleem: op verschillende momenten worden de margins gereset, zodat het knopje weer wit wordt. Ik heb dit weten af te vangen, door in de volgende methoden/notifications de margins te forceren naar wat ik wilde:

• CreateWnd
• DoEnter
• DoExit
• MouseDown
• MouseMove
• CreateHandle
• WM_CAPTURECHANGED
• WM_SETFOCUS
• WM_MOUSEACTIVATE
• WM_SIZE

Zoals je ziet, dat zijn er nogal wat. Maar in al deze methoden/notifications kunnen de margins gereset worden, zodat ik ze weer opnieuw moet instellen. Dit heeft tot gevolg dat de control twee keer getekend wordt, en dat leidt weer tot een knipperend effect.

Weet iemand waardoor deze margins gereset worden? Is dit op een normale (en betrouwbare) manier op te vangen? Of zijn de margins op een andere manier in te stellen waardoor de control ze wel "onthoudt"?

Ohja, wat code nog. De code om de margins in te stellen is vrij eenvoudig:
Delphi:
1
2
with ClientRect
do Perform(EM_SETMARGINS, EC_RIGHTMARGIN, (Bottom - Top) shl 16);

日本!🎌


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Bij mijn weten hoef je die code alleen te zetten in de WM_SIZE en in de CreateWnd. Heb je een stukje code waar uit blijkt dat dat niet genoeg is?

We adore chaos because we like to restore order - M.C. Escher


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
ff quick & (heel erg) dirty dan:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
unit MarginEdit;

interface

uses
  Windows, Messages, Classes, Graphics, Controls, StdCtrls;

type
  TMarginEdit = class(TCustomEdit)
  private
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
  public
    procedure CreateWnd; override;
  end;

implementation

procedure TMarginEdit.CreateWnd;
begin
inherited CreateWnd;
with ClientRect
do Perform(EM_SETMARGINS, EC_RIGHTMARGIN, (Bottom - Top) shl 16);
end;

procedure TMarginEdit.WMPaint(var Message: TWMPaint);
begin
inherited;
with ClientRect
do DrawFrameControl(GetDC(Handle),
      Rect(Right - (Bottom - Top), Top, Right, Bottom),
      DFC_BUTTON, DFCS_BUTTONPUSH);
end;

procedure TMarginEdit.WMSize(var Message: TWMSize);
begin
inherited;
with ClientRect
do Perform(EM_SETMARGINS, EC_RIGHTMARGIN, (Bottom - Top) shl 16);
end;

end.


Zet zo'n ding in je form met...
Delphi:
1
InsertControl(TMarginEdit.Create(Self));

En geef em maar es focus. De margin wordt dan gereset. Bij mij tenminste.

/edit
een heel component in 42 regels, dat moet toch een soort van record zijn :)

[ Voor 5% gewijzigd door _Thanatos_ op 03-01-2004 00:01 ]

日本!🎌


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Werkt perfect hier. Ik gebruik precies de code die hier staat en maak m ook precies zo aan. Op het form staat nog een gewonte TEdit die standaard de focus heeft. Als ik dan met de muis jouw component de focus geef en ik begin te typen is de marge no intakt. Ik loop niet door de button heen. Geprobeerd in D5 win2k en D7 winXP. Voor de lol heb ik het ook nog onder D8 for .Net geprobeerd en de code draaide zonder wijzigingen en zonder problemen onder winXP.

PS:
Applications should not need to call InsertControl directly... At runtime, use the Parent property of the child control...
bron: Delphi help
Normaal zet je de Parent property van de TMarginEdit instantie, bijvoorbeeld op Self (het Form).

Je zou ook een TSpeedButton kunnen gebruiken ipv het hele button gedrag zelf te gaan maken.

We adore chaos because we like to restore order - M.C. Escher


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Dat is wel erg weird. Misschien kan het aan een overblijfsel van dat vervloekte MouseWare liggen (had ik ook nooit moeten installeren), maar het lijkt me wel sterk.

btw, ik gebruik juist geen speedbutton omdat ik de knop ín de edit wil en niet ernaast. Een speedbutton in de edit kan wel, maar dan komt de tekst er nog steeds overheen. Bovendien wil ik meer dan alleen maar 1 knopje. Het moet uiteindelijk een spinedit à la coreldraw worden (waarin je de waarde dus kunt wijzigen door te slepen).

edit: net ff op een kale win98 geprobeerd en het werkt perfect. Maar nu rest nog steeds dus de vraag waardoor in hemelsnaam dan die margins gereset kunnen worden...

[ Voor 15% gewijzigd door _Thanatos_ op 03-01-2004 15:57 ]

日本!🎌


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ja, vreemd, maar we mogen wel concluderen dat het niet door Delphi komt, maar door een stukje vreemde software aan jouw kant.

Ik bedoelde niet dat je speedbutton kon gebruiken op de manier dat jij voorsteld, maar gewoon precies zoals je nu hebt. Met de margins, maar dan in het gedeelte wat overblijft 1 (of twee) speedbutton(s) zetten en niet zelf gaan tekenen met DrawFrameControl enz. :)

We adore chaos because we like to restore order - M.C. Escher


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Hmm, ik heb vanalles geprobeerd, zelfs andere machines waarop ik vrijwel dezelfde software geinstalleerd heb. Daarop werkt dit allemaal, behalve dus mijn PC. Ik kan veilig concluderen dat het aan de volgende dingen niet ligt:
  • Een driver (in veilige modus gaat het ook fout)
  • Videokaart/driver (in een remote desktop session gaat het ook fout)
  • Norton Antivirus (heb ik gedeïnstalleerd)
  • MouseWare (heb ik op een andere PC geïnstalleerd en zorgde niet voor dit effect)
Ik ben er via Winspector achter gekomen dat er wel heel erg vaak WM_APP+15667 naar de control gepompt wordt, maar ook zo nu en dan (kan niet precies achterhalen wanneer, het lijkt nogal random) WM_APP+12314 en WM_APP+12315.

Die eerste wordt op PC's waar dit op werkt ook verzonden, maar slechts één keer. De andere heb ik nog nooit van m'n leven gezien.

/edit
Zucht, ik heb gevonden wat dit veroorzaakt. In Windows XP (en 2000?) kun je ondersteuning voor van-rechts-naar-links talen en aziatische talen installeren. Dat heb ik dus. Op een PC waarop dit werkte heb ik die twee vinkjes ook aangezet, in configuratiescherm -> landinstellingen dus, en toen liep mijn control de mist in ;)

Met deze info kan een van u misschien helpen met een oplossing? Want er zijn vast meer gebruikers die chinese letters mooier vinden dan vierkantjes.

[ Voor 23% gewijzigd door _Thanatos_ op 04-01-2004 00:19 ]

日本!🎌


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Als ik het goed bereken vind ik het volgende:

WM_APP+15667 = CN_CTLCOLOREDIT
WM_APP+12314 = CM_ENTER
WM_APP+12315 = CM_EXIT

Dit zijn Delphi's eigen windows messages die soms verstuurd worden tussen de componenten. Ik kan niets in de VCL vinden dat reageert op CN_CTLCOLOREDIT. CN_CTLCOLOREDIT's windows equivalent is WM_CTLCOLOREDIT, maar ook die wordt niet gebruikt in de VCL. Normaal wordt deze gebruikt om de achtergrond kleur aan te kunnen geven van een edit control. Ik zie niet in waarom dat wat te maken heeft met je Chinese tekens, maar misschien is het genoeg om de margins te zetten na het ontvangen van deze message.

We adore chaos because we like to restore order - M.C. Escher


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Maar dan gaat ie dus ontzettend knipperen, en dat ziet er natuurlijk niet zo profi uit. Ik heb al ontdekt dat als ik er een multiline edit van maak, in CreateParams dus, en EM_SETRECTNP gebruik om de "marges" in te stellen, het opeens stukken beter werkt. Ik kan niet testen of het met rechts-naar-links schriften ook werkt, maar daar ging het ook niet om (ik heb ze alleen maar geinstalleerd, ik gebruik ze verder niet nu).

Nu roep ik die EM_SETRECTNP dus aan in SetBounds, MouseDown en KeyDown (en op het moment dat de marges moeten veranderen uiteraard). Dat lijkt voldoende te zijn en het knippert totaal niet.

日本!🎌


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 24-11 12:27

Tomatoman

Fulltime prutser

Offtopic:
Maar meteen even een vraag ertussendoor die met marges en alignment te maken heeft: weet iemand hoe je right-to-left alignment in werking kunt zien zonder Windows in te stellen op een of andere Arabische taal? Ik heb geen idee hoe ik in mijn controls kan testen of right-to-left alignment naar behoren werkt.

Een goede grap mag vrienden kosten.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Dat doen de BiDiMode/ImeMode properties toch?

日本!🎌

Pagina: 1