Toon posts:

[Delphi] Muisknoppen events uitschakelen bij een listview

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een listview die altijd op Enabled := True staat. Ik disable hem nooit omdat je anders de selectie van de listview niet meer kan zien.

Alleen ik heb dus zelf wel een mechanisme er in gebouwd dat je de listview niet meer kan bedienen (dus toetsen werken niet meer, en je kan de listview niet meer de focus laten krijgen) in edit mode.

In de Enter event heb ik daarvoor de volgende code staan:

Delphi:
1
2
  if (not ListViewEnabled) or (lstvw_Verpakkingen.Items.Count = 0) then
    SelectNext(lstvw_Verpakkingen, True, True)


Dit werkt allemaal prima. Alleen er is 1 probleem. Als ik de listview uitgeschakeld heb (dus eigen variabele ListViewEnabled = False) kan ik wel met de muis selectie rectangle's tekenen. Hierdoor gaat het ook mis als ik later weer uit de edit mode ben en de listview dus weer ingeschakeld is.

Kortom wat ik wil is dus dat ik er voor wil zorgen dat men niet een selectie rectangle kan tekenen. Is dit mogelijk?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

De mouse down windows message wegkapen.

bijvoorbeeld
Delphi:
1
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;

en dan geen inherited doen als not ListViewEnabled

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


Verwijderd

Topicstarter
LordLarry schreef op 08 December 2002 @ 15:07:
De mouse down windows message wegkapen.

bijvoorbeeld
Delphi:
1
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;

en dan geen inherited doen als not ListViewEnabled
Als ik dit toepas, kan ik nog steeds een selectie rectangle tekenen.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Dan heb je denk ik pech gehad. Het zit dan te diep in windows ingebakken.

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


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 22:50

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 08 December 2002 @ 14:13:
Dit werkt allemaal prima. Alleen er is 1 probleem. Als ik de listview uitgeschakeld heb (dus eigen variabele ListViewEnabled = False) kan ik wel met de muis selectie rectangle's tekenen. Hierdoor gaat het ook mis als ik later weer uit de edit mode ben en de listview dus weer ingeschakeld is.
Wat gaat er mis??

Als je view enabled is kan je nog wel de selected veranderen dus? Het lijkt me dat de focus niet van het item verschuift. Dus als je kijkt of het geselecteerde item ook het item is wat de focus heeft moet je toch nog wel het 1 en ander kunnen proberen?

Je zou ook nog eens in de source van de TListView kunnen spitten, en hier zelf een klasse vanaf leiden die niet de selectie veranderd als de listview enabled is.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Inmiddels heb ik een oplossing voor mijn probleem gevonden. Ik zal het toch hier posten omdat er misschien andere mensen nog wat aan hebben.

Met deze code:

Delphi:
1
2
3
4
5
6
7
8
9
10
Application.OnMessage := NegeerBerichten;

procedure Tfrm_ArtikelVerpakking.NegeerBerichten(var Msg: TMsg;
  var Handled: Boolean);
begin
  if (not ListViewEnabled) and (Msg.hwnd = lstvw_Verpakkingen.Handle) then
    Handled := True
  else
    Handled := False;
end;


is het niet meer mogelijk om items in de listview te selecteren.

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

LordLarry schreef op 08 december 2002 @ 22:00:
Dan heb je denk ik pech gehad. Het zit dan te diep in windows ingebakken.
Dat denk ik niet (ondanks dat de oplossing er al is). Waarschijnlijk is het je wel eens opgevallen dat een delphi applicatie veel groter in omvang is dan van de meeste progtalen (vb of c++builder). Dit komt omdat het VCL team bij Borland alle componenten zelf geschreven heeft in Object Pascal. Dit betekent volgens mij dat je meer invloed kunt hebben op de componenten en dit soort dingen makkelijk uit zou kunnen zetten.

Daar komt bij dat Windows een zogenaamd berichten systeem is. Als je een bericht opvangt (en dat wel op de juiste plaats doet) kun je dit soort dingen afvangen. Je kan zelfs een progje schrijven dat alle muis events afvangt en bijvoorbeeld random gaat klikken. Levert leuke effecten op moet ik zeggen :)

www.fendt.com | Nikon D7100 | PS5


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:42
[nohtml]
FendtVario schreef op 17 January 2003 @ 16:57:
[...]


Dat denk ik niet (ondanks dat de oplossing er al is). Waarschijnlijk is het je wel eens opgevallen dat een delphi applicatie veel groter in omvang is dan van de meeste progtalen (vb of c++builder).
Dit komt omdat het VCL team bij Borland alle componenten zelf geschreven heeft in Object Pascal. Dit betekent volgens mij dat je meer invloed kunt hebben op de componenten en dit soort dingen makkelijk uit zou kunnen zetten.
Dit is een beetje onzin.
C++ Builder gebruikt net dezelfde VCL als Delphi, dus als een C++ Builder executable al kleiner is dan een Delphi executable kan het daar niet aan liggen.
Ook VB maakt gebruik van DLL file's met daarin controls in (net zoals Delphi en C++ Builder als je de libraries niet in de exe meelinkt).

https://fgheysels.github.io/


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Verwijderd schreef op 17 January 2003 @ 16:35:
[code=delphi]
is het niet meer mogelijk om items in de listview te selecteren.
Nee, maar dit is wel erg drastisch. In plaats van de juiste messages te blokkeren blokkeer je nu alles. Ik denk ook zelfs dat je de paint messages blocked en dat als je je form beweegt of een ander form erover haalt je listview niet gerefreshed wordt. Ik zou voorstellen om alleen de juiste berichten eruit te filteren, zoals ik ook al eerder heb voorgesteld.

Verder is Application.OnMessage gebruiken niet erg netjes, snel en kan niet hergebruikt worden. Wat als je 2 listviews hebt of 3? ga je dan elke keer die functie aanpassen? Elke bericht van je app komt er langs, en je bouwt er zo wel een onnodige vetraging in. Je kan deze code ook makkelijk in je eigen afgeleide van TListView bakken dmv het overriden van de WndProc routine. Netjes properties gerbruiken om het aan en uit te zetten en je hebt een pracht component die je meer kan gebruiken in welke app dan ook en het enige wat je dan hoeft te doen is het component op een form gooien zoals je normaal al gewend was. Dit vergt wel wat kennis van componenten, windows messages en Delphi in het algemeen.

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


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

FendtVario schreef op 17 januari 2003 @ 16:57:
Dat denk ik niet (ondanks dat de oplossing er al is). Waarschijnlijk is het je wel eens opgevallen dat een delphi applicatie veel groter in omvang is dan van de meeste progtalen (vb of c++builder). Dit komt omdat het VCL team bij Borland alle componenten zelf geschreven heeft in Object Pascal. Dit betekent volgens mij dat je meer invloed kunt hebben op de componenten en dit soort dingen makkelijk uit zou kunnen zetten.
Je hoeft mij niets te vertellen over Delphi hoor :) En zoals whoami al zegt, BCB gebruikt ook gewoon VCL dus de grote zegt niet. Dat verschil in grote komt door het gebruikt van runtime packages die Delphi ook heeft, maar toevallig bij BCB standaard aan staan. VC++ maakt redelijk kleine apps als je het puur winapi doet. Gebruik je als MFC moet je ook de runtime packages van VC++ mee gaan rekenen.

De VCL is inderdaad een laag bovenop de winapi, maar deze laag is meestal erg dun. En dat is zeker het geval voor TListView. De VCL tekend niet de selectie in een ListView, dat doet de winapi. Het is niet Delphi die zegt dat de ListView een item moet selecteren nadat er op een item gedrukt is. Tis de winapi die de VCL meedeelt dat er wat gebeurt is. De winapi legt de interface vast en daar kan ook de VCL niet altijd omheen. Kennelijk is er wel een message die voorkomt dat er een selectie rectangle gemaakt kan worden, maar je zal m eerst moeten achterhalen :) Ik zou graag weten welke dat dan is.

Je kan wel zorgen dat er niets geselecteerd wordt dmv van de OnSelectItem event, maar je zal dan nog altijd een selectie rectangle getekend zien worden. Als je daarbij de MultiSelect property uit zet wordt ook die niet getekend. Het enige wat je dan nog ziet in de focus.

Maar je hebt gelijk, als je iets verder kijkt dan de VCL diep is kan nog meer trukjes uit de kast halen.

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


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

LordLarry schreef op 17 January 2003 @ 20:22:
[...]

Maar je hebt gelijk, als je iets verder kijkt dan de VCL diep is kan nog meer trukjes uit de kast halen.
Blij dat je het hierover met me eens bent. :)

C++Builder heeft het bij mij nog niet verder geschopt dan een paar keer opstarten en kijken. Ik had het idee dat een in C++Builder ontwikkelde applicatie zonder toevoeging van andere bestanden (zoals de runtime packages of dll's) op andere systemen kon draaien.

www.fendt.com | Nikon D7100 | PS5


Verwijderd

Topicstarter
LordLarry schreef op 17 January 2003 @ 19:41:
[...]Je kan deze code ook makkelijk in je eigen afgeleide van TListView bakken dmv het overriden van de WndProc routine. Netjes properties gerbruiken om het aan en uit te zetten en je hebt een pracht component die je meer kan gebruiken in welke app dan ook.
Klopt daar heb je helemaal gelijk in en dat ga ik dan ook doen.

  • hamburger
  • Registratie: April 2000
  • Niet online

hamburger

BOOOM!!!

Niet gewoon de property HideSelection uitzetten?

edit:
Als ik die uitzet en Enabled op false dan wordt alles geselecteerd

[ Voor 47% gewijzigd door hamburger op 17-01-2003 22:55 ]


Verwijderd

Topicstarter
hamburger schreef op 17 januari 2003 @ 22:52:
Niet gewoon de property HideSelection uitzetten?

edit:
Als ik die uitzet en Enabled op false dan wordt alles geselecteerd
Ja maar ik wil het zo niet hebben, want dan worden alle normale items grijs en de geselecteerde fel blauw.

Verwijderd

Topicstarter
Ik heb inmiddels een nieuw component gemaakt en daarin een aantal messages afgevangen. Op zich werkt het goed, alleen het probleem is dat als je de header van een listview resized en vervolgens de muisknop loslaat, dan de listview toch de focus krijgt (alleen je ziet het niet, de selectie wordt niet blauw, maar de listview reageert wel op de keyboard input). Maar ik snap het niet, want ik vang toch de WM_SETFOCUS af. Hoe kan het dan dat de listview toch de focus krijgt?

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
procedure TlistviewDisable.DoEnter;
begin
  if not DisableSelection then
    inherited;
end;

procedure TlistviewDisable.WndProc(var Message: TMessage);
begin
  if not DisableSelection then
    inherited
  else
    if (Message.Msg <> WM_LBUTTONDOWN) and
       (Message.Msg <> WM_RBUTTONDOWN) and
       (Message.Msg <> WM_SETFOCUS) and
       (Message.Msg <> WM_LBUTTONUP) and
       (Message.Msg <> WM_RBUTTONUP) then
      inherited;
end;
Pagina: 1