Autor Téma: Dokovanie okien  (Přečteno 8749 krát)

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #15 kdy: 17-12-2012, 15:32:00 »
Už len tú signalizáciu, že dôjde k dokovaniu. Verím, že to v tom druhom odkaze nájdem. Je to súčasť Delphi - myslím tú ukážku.
Tvoje riešenie som si ešte nepozrel :)
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Dokovanie okien
« Odpověď #16 kdy: 18-12-2012, 08:41:03 »
Tvoje riešenie som si ešte nepozrel :)

Pokud tvůj (jistě dobrý) přístup "Ale skôr než sa na to pozriem, tak to skúsim najprv sám." dovedeš až k takové dokonalosti, že si ani neprohlédneš, co ti ostatní připravili a jak se ti snažili pomoci, tak dopadneš tak, že ti nikdo neporadí... Navíc ještě, když ten kód je v takovém stavu, že ho máš přenesený do Delphi a zkompilovaný asi tak za 6,3 vteřiny. :o
Embarcadero Technology Partner

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #17 kdy: 18-12-2012, 09:19:38 »
Už som si to pozrel. Moja živnosť nie je programovanie. To už by som na tom svete nebol. K Delphi sa dostávam večer a cez víkend. A najprv som chcel sám urobiť čo najviac. To mi okrem iného pomohlo ako tak pochopiť Tvoju ukážku. Trvá mi to dlhšie, lebo sa snažím hrabať aj v helpe aby som vedel o čom to je.

Tvoja ukážka je na mňa veľmi komplikovaná. Myslím tým volanie funkcií krížom krážom. Ale vnikám do toho.
Mám na srdci tri veci

1) V helpe (MSDN) má CmdType len dve návratové hodnoty 0 a 1. V príklade vracia rôzne. Viď podmienka
if (fxLastCmdType = WM_SYSCOMMAND_MOVE_WINDOW) then

2) nerozumiem tejto podmienke
.    if not (Message.WindowPos^.flags and SWP_NOMOVE = SWP_NOMOVE) and
.      (Self.Owner is TfrmMaster) then
Message.WindowPos^.flags - tento zápis je pre mňa španielska dedina. Ak sa vráti nula je Messge nil, alebo to znamená niečo iné?
SWP_NOMOVE = SWP_NOMOVE - Podľa mňa musí byť vždy True. Porovnávame jednu a tú istú hodnotu.

3) Riešenie je komplexné a univerzálne. Ale mám problém s predstavením si jeho aplikovaním do živého projektu. Konkrétne

  TfrmMaster = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
atď.
Ja budem mať zakaždým iný už hotový formulár. Vidím dve možnosti. Prvá je z programového (aj môjho) pohľadu principiálne zlá

I.) Všetky tieto vlastnosti a spol. budem definovať v každom MasterForm. Bŕŕŕ.

II.) Vytvorím si nejaký objekt do ktorého potom priradím patričný formulár. A tu sa nechytám. Aký typ objektu to vlastne má byť. Predpokladám niečo na spôsob
  TDockedForm = class;
...
  TDockedForm = class(TForm)

Ale ako tam dostanem svoj formulár + rozšírenie o požadované vlastnosti? Tu som úplne nulový.
Už teraz veľké ďakujem za uvedenú ukážku a prípadnú odpoveď.

Poznámka:
Pri Tvojom riešení, priskočenie Detail k Master ak sa nachádza v "magnetickom poli", nepotrebuje signalizáciu dokovania. Tá sa dá riešiť pomocou Alphablend + BorderStyle = bsNone.

Prosba: Kde by som si mohol viac komplexne prečítať v češtine o Message? Niečo mám v angličtine, ale s tou sa nekamarátim a niekedy nepomáha ani slovník. Ďakujem.
« Poslední změna: 18-12-2012, 09:22:12 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2594
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Dokovanie okien
« Odpověď #18 kdy: 18-12-2012, 10:40:21 »
1) V helpe (MSDN) má CmdType len dve návratové hodnoty 0 a 1. V príklade vracia rôzne. Viď podmienka
if (fxLastCmdType = WM_SYSCOMMAND_MOVE_WINDOW) then
No to nevim, na co ses koukal  :o

Pri praci se zpravami v Delphi je treba podivat se do unit messages.pas. Zprava ve Windows API je kod zpravy (message) a jeji dva nepovinne parametry WParam a LParam (historicky Word a Long) a pri jejim zpracovani se nekdy vraci nejaka navratova hodnota. A v MSDN zpravy hledas vyhradne pres hodnotu kodu zpravy tj. nejake WM_xxxx, LB_xxx milion dalsich.

V Delphi to vsechno nastrkali do recordu TMessage a pak pro ruzne hodnoty kodu (typu zpravy) nadefinovali hafo dalsich recordu, ktere jen jinak formatuji tu zakladni TMessage a AFAIK, tak uz to nezdokumentovali, cimz IMHO udelali vic skody nez uzitku, protoze pri praci se zpravami se vyhradne pouziva popis z MSDN.

Ty potrebujes znat zaklady Windows API. Nejaka klasicka dila jako Petzold apod. vysla i v cestine, ale to je pro tebe zbytecne rozsahla a detailni materie, tobe by melo stacit projit nejaky tutorial k API, namatkou jsem vygooglil http://programujte.com/clanek/2005122808-win32-api-uvod/


2) nerozumiem tejto podmienke
.    if not (Message.WindowPos^.flags and SWP_NOMOVE = SWP_NOMOVE) and
.      (Self.Owner is TfrmMaster) then
Message.WindowPos^.flags - tento zápis je pre mňa španielska dedina.

Message je typu TWMWindowPosMsg, ktera to co je v MSDN LPARAM nazyva WindowPos, coz je ukazatel na TWindowPos (v MSDN record WINDOWPOS), ktery ma clen flags


SWP_NOMOVE = SWP_NOMOVE - Podľa mňa musí byť vždy True. Porovnávame jednu a tú istú hodnotu.
Jenomze je treba divat se na to jako na cely vyraz, ktery obsahuje vice operatoru s ruznou prioritou. Ta prvni cast
Kód: Delphi [Vybrat]
  1. Message.WindowPos^.flags and SWP_NOMOVE
je bitova operace logickeho soucinu, ktere se rika maskovani, protoze slouzi k tomu, ze vynuluje bity, ktere te nezajimaji. A vysledek v tomto pripade porovnava s maskou SWP_NOMOVE cili se pta, jestli je ve flags nastaveno SWP_NOMOVE na jednicky.

Tento i predchozi bod - to je neznalost zakladu programovani a jazyka Pascal - to by chtelo nejakou ucebnici Pascalu.

Prosba: Kde by som si mohol viac komplexne prečítať v češtine o Message?
Message = porozumeni principum Windows API. Jejich popis je celkem dobre popsan (anglicky) pod kodem zpravy v MSDN, v cestine nic takoveho AFAIK neexistuje. A pak nahlednout do Delphi messages.pas, abys videl, jak Bordeland Windows API zamlzil, cas od casu je treba nahlednout i do windows.pas, protoze prepis API neni logicky konzistentni, nekde maji ukazatele, nekde naplacali var argumenty apod.

Jinak my treba z duvodu srozumitelnosti kodu ty Delphi specifika krome TMessage nepouzivame a drzime se API.

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #19 kdy: 18-12-2012, 11:06:01 »
Čítam ako chcem :D Nedošlo mi, že tú podmienku musím čítať postupne zľava doprava. Vďaka za vysvetlenie.
No to nevim, na co ses koukal  - daj si do helpu (filter na SDK) cmdtype a hneď uvidíš.
 
« Poslední změna: 18-12-2012, 11:09:28 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1436
  • Karma: 34
    • Pepak.net
Re:Dokovanie okien
« Odpověď #20 kdy: 18-12-2012, 12:25:53 »
Čítam ako chcem :D Nedošlo mi, že tú podmienku musím čítať postupne zľava doprava.
Ne zleva doprava! Podle priorit operátorů!!
(Osobně ale radši v takovýchto případech používám závorky, je to pak takové přehlednější)

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Dokovanie okien
« Odpověď #21 kdy: 18-12-2012, 13:17:55 »
Už som si to pozrel. Moja živnosť nie je programovanie. To už by som na tom svete nebol. K Delphi sa dostávam večer a cez víkend.
Já jsem na tom stejně :(

Tvoja ukážka je na mňa veľmi komplikovaná. Myslím tým volanie funkcií krížom krážom.
Nezdá se mi, master a docked spolu komunikují pouze přes 5 public funkcí a properties (klidně si je můžeš dát do private/protected). Klíčové jsou ty messages, zbytek je taková nutná omáčka, kterou si ale můžeš vymyslet a přepsat, jak chceš.

1) V helpe (MSDN) má CmdType len dve návratové hodnoty 0 a 1. V príklade vracia rôzne. Viď podmienka
if (fxLastCmdType = WM_SYSCOMMAND_MOVE_WINDOW) then
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360%28v=vs.85%29.aspx

WM_SYSCOMMAND_MOVE_WINDOW tam chybí, ale je v komentářích:
Citace: btarb24
omitted command
SC_DRAGMOVE = 0xf012

Happens when you drag a window. I specifically get it when i send WM_NCLBUTTONDOWN with HT_CAPTION. It also seems to be followed by a WM_ACTIVATE.

3) Riešenie je komplexné a univerzálne. Ale mám problém s predstavením si jeho aplikovaním do živého projektu.

Ale ako tam dostanem svoj formulár + rozšírenie o požadované vlastnosti? Tu som úplne nulový.
Už teraz veľké ďakujem za uvedenú ukážku a prípadnú odpoveď.

Není nic jednoduššího. Ulož si kód s master/docked do extra unity a v kódu tvého delphi formuláře ji přidej do uses a pak přepiš:

Kód: Delphi [Vybrat]
  1.   TForm1 = class(TForm)
  2.  

na

Kód: Delphi [Vybrat]
  1.   TForm1 = class(TMasterForm)
  2.  

To samé uděláš pro všechny docked formuláře (můžeš jich mít samozřejmě více různých typů, které tímto pádem sdílejí jeden kód).

Jen v tomto případě nebude funguvat podmínka v TDockedForm:
Kód: Delphi [Vybrat]
  1.   (Self.Owner is TMasterForm)
  2.  

tam si musíš vymyslet něco jiného (např Application.MainForm apod).
Embarcadero Technology Partner

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #22 kdy: 18-12-2012, 13:31:13 »
Večer uvidím. Dám vedieť.

to pepak. Chytáš ma za slovo. Ale máš pravdu. Ja tie zátvorky používam aj keď nie sú potrebné. if (a=b) then. Stačí nepozornosť/neuvedomiť si a mať v a typ Boolean. Potom sa bez zátvoriek nestíham čudovať.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2358
  • Karma: 102
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:Dokovanie okien
« Odpověď #23 kdy: 18-12-2012, 14:33:52 »
[Jinak my treba z duvodu srozumitelnosti kodu ty Delphi specifika krome TMessage nepouzivame a drzime se API.

No to si myslím, že není IMHO moc dobré. Celkem sranda je při přechodu na 64bit, kdy se např. velikosti stejné zprávy pod 32bit a 64bit celkem liší a Delphi to právě odstiňuje tak, že přidává zarovnání kde je třeba. 
Během beta testu se dokonce dělal nástroj, který proběhl zdrojáky RTL a porovnával velikosti proti VC jak pro 32bit, tak pro 64bit.

V novějších (64bit kompatible verzích) je TMessage definován následovně (všimni si použití WPARAM, LPARAM)
Kód: Delphi [Vybrat]
  1.   TMessage = record
  2.     Msg: Cardinal;
  3.     case Integer of
  4.       0: (
  5.         WParam: WPARAM;
  6.         LParam: LPARAM;
  7.         Result: LRESULT);
  8.       1: (
  9.         WParamLo: Word;
  10.         WParamHi: Word;
  11.         WParamFiller: TDWordFiller;
  12.         LParamLo: Word;
  13.         LParamHi: Word;
  14.         LParamFiller: TDWordFiller;
  15.         ResultLo: Word;
  16.         ResultHi: Word;
  17.         ResultFiller: TDWordFiller);
  18.   end;
  19.  
Kde to TDWordFiller má různou velikost v závislosti na OS. Dříve:

Kód: Delphi [Vybrat]
  1.   TMessage = packed record
  2.     Msg: Cardinal;
  3.     case Integer of
  4.       0: (
  5.         WParam: Longint;
  6.         LParam: Longint;
  7.         Result: Longint);
  8.       1: (
  9.         WParamLo: Word;
  10.         WParamHi: Word;
  11.  
  12.         LParamLo: Word;
  13.         LParamHi: Word;
  14.  
  15.         ResultLo: Word;
  16.         ResultHi: Word);
  17.  
  18.   end;
  19.  

Ale proti gustu žádný dišputát.
Embarcadero MVP - Czech republic

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2594
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Dokovanie okien
« Odpověď #24 kdy: 18-12-2012, 18:09:47 »
V novějších (64bit kompatible verzích) je TMessage definován následovně (všimni si použití WPARAM, LPARAM)
Tak spravnou definici pomoci WPARAM a LPARAM vidim uz v D2009. V D2007 je jeste spatna, prestoze ve Windows maji WPARAM a LPARAM zavedene. Zkratka nedusledni kutilove (td)

Offline TLama

  • Guru
  • *****
  • Příspěvků: 597
  • Karma: 31
    • Verze Delphi: 7, 2009, XE3
Re:Dokovanie okien
« Odpověď #25 kdy: 18-12-2012, 18:18:23 »
V novějších (64bit kompatible verzích) je TMessage definován následovně (všimni si použití WPARAM, LPARAM)
Tak spravnou definici pomoci WPARAM a LPARAM vidim uz v D2009. V D2007 je jeste spatna, prestoze ve Windows maji WPARAM a LPARAM zavedene. Zkratka nedusledni kutilove (td)

Navíc datový typ pro WPARAM byl nadefinovaný správně až v Delphi XE2.

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #26 kdy: 19-12-2012, 08:43:22 »
Spojazdnil som to
//Jen v tomto případě nebude funguvat podmínka v TDockedForm:
//  (Self.Owner is TMasterForm)

Opísal som z Tvojho a riešim to takto:

  TfrmDocked1.CreateNew(Self).Show;
....
  TfrmDockedxx.CreateNew(Self).Show;
 
A študujem to naďalej  :-*
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #27 kdy: 20-12-2012, 10:42:08 »
Tak to je zle. Aplikácia o formuláry nič nevie. Doplnil som vlastnosť MyOwnera a test robím na ňu. Vyzerá to, žeby to malo byť v poriadku.

Vy ma tu ešte naučíte pracovať objektovo :D
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #28 kdy: 23-12-2012, 10:41:36 »
Prosím o vysvetlenie.
 
Kód: Delphi [Vybrat]
  1.   Application.CreateForm(TfrmBankAccount, frmBankAccount);
  2.   frmBankAccount.jvfrmstrg1.AppStoragePath := 'frmBankAccountPartner\';
  3. xx  frmBankAccount.Show;
  4.   Application.CreateForm(TfrmPartner, frmPartner);
  5.   frmBankAccount.MyOwner := TProprietorForm(frmPartner);
  6.   frmPartner.Show;
  7.   Self.Visible := False;
  8.   if aValProg[15, 3] then
  9.   begin
  10.     if ToLeft(frmPartner, frmBankAccount) or ToRight(frmPartner, frmBankAccount) then
  11.       frmPartner.StartDocking(frmBankAccount); // registrácia okna
  12.   end;
  13.   frmBankAccount.Hide;
  14.  

Ak nepoužijem označený riadok xx, tak sa mi dané okno nezaregistruje. Master ho neťahá za sebou. Potom už je jedno či je viditeľné alebo nie.
Okno je vytvorené a tým pádom aj prijíma správy. Prečo sa potom frmBankAccount nezaregistruje bez frmBankAccount.Show?
 
Viem to riešiť (prebliknutie okna) zneviditeľnením okna. Verím, že existuje menej náročný spôsob. Ďakujem.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4455
  • Karma: 39
    • Verze Delphi: XE7 professional
Re:Dokovanie okien
« Odpověď #29 kdy: 19-01-2013, 14:29:56 »
mám
Kód: Delphi [Vybrat]
  1. procedure TDockedForm.WMEnterSizeMove(var Message: TMessage);
  2. begin
  3.   if not aValProg[25, 3] then
  4.     Exit;
  5.   AlphaBlend := True;
  6.   AlphaBlendValue := 150;
  7.   BorderStyle := bsNone;
  8.   Color := clHighlight;
  9.   FormStyle := fsStayOnTop;
  10.   VisibleEdit(Self as TForm, False);
  11. end;
  12.  
Rád by som dosiahol, aby sa to nevykonalo keď je menená veľkosť okna. Neviem zistiť či je stav Drag alebo Resize.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.