Avatar billede rasmusw Nybegynder
26. april 2001 - 18:54 Der er 16 kommentarer og
2 løsninger

windowstyle ændring fra mdi child til normal og med separat knap i taskbar

Jeg er ved at skrive en applikation som laver forskellige grafer der bliver kontinuerligt opdateret.
Jeg ville gerne have at graf-vinduerne kan være både MDI børn, og som helt separate vinduer der ikke bliver minimeret sammen med resten af programmet. mIRC kan gøre det med download-vinduerne, men jeg har ikke den fjerneste anelse om hvor der skal begyndes. Når man gør det i mIRC optræder vinduet med egen knap i taskbaren, og også i Alt-TAB listen. Det vil også være ret fedt at have med, men i første omgang bare at undgå at vinduet bliver minimeret når min applikation gør.

Alle forslag er velkomne.
Avatar billede borrisholt Novice
27. april 2001 - 08:02 #1
rasmusw >> For at kunne svare på dette spørgsmål  er jeg nød til at vide om du bruger C++ Builder eller MFC eller noget helt tredje ...

Jeg har lige lave et eksempel i Delphi (samme ting i C++ Biuilder). Det var nemt nok. 5 Linjers kode så var den i vinke ... Jeg elsker Borland for det !

jens B
Avatar billede soepro Nybegynder
27. april 2001 - 08:19 #2
Jens >> Det skal vel gøres ved oprettelsen af vinduet eller ??? Vha. FormStyle = fsMDIChild eller fsNormal eller hvad ???
Avatar billede borrisholt Novice
27. april 2001 - 08:21 #3
yep ... Bortset fra du ikke gør det ved oprettelse af vinduet, men ved tryk på en knap ....

Jens B
Avatar billede soepro Nybegynder
27. april 2001 - 08:25 #4
OK - det troede jeg bare ikke at man kunne når først formen var dannet - smart nok.
Avatar billede rasmusw Nybegynder
27. april 2001 - 08:27 #5
det er C++ builder, men 5 liniers delphi er også fint.
Avatar billede borrisholt Novice
27. april 2001 - 08:34 #6
du opretter et nyt projekt.

Sætter din main form (form1)til at være af typen fsMDIForm du ved From1Style = fsMDIForm.
Så laver du din form2 og sætter typen til at være fsMDIChild.

Nu har du en alm. MDI APP.

På Form 2 placer du en knap og skriver følgende :

procedure TForm2.Button1Click(Sender: TObject);
begin
if Button1.Caption = \'MDI\' then
begin
  Form2.FormStyle := fsNormal;
  Button1.Caption := \'NOT MDI\';
end
else
begin
  Form2.FormStyle := fsMDIChild;
  Button1.Caption := \'MDI\';
end;
end;

(konveter selv til C++)

Jens B
http://www.fotx.net/borrisholt
Avatar billede borrisholt Novice
27. april 2001 - 08:41 #7
orv ja captionen på din kanp skal hede MDI for det passer ...
Avatar billede rasmusw Nybegynder
27. april 2001 - 09:03 #8
det er et godt stykke hen ad vejen, men der er problemer:
I hjælpen under TCustomForm::FormStyle står der til sidst: \"Note: It is not advisable to change FormStyle at runtime.\" - Jeg ved ikke hvad \"not advisable\" dækker over.
Og, form2 bliver stadig minimeret når form1 bliver minimeret.
Avatar billede rasmusw Nybegynder
27. april 2001 - 12:27 #9
jeg har fundet ud af noget mere selv. Der er to elementer i det:
1. At give formen en egen knap på taskbaren, og
2. at undgå at den minimerer når hovedvinduet gør.

1:
void __fastcall TForm2::CreateParams(TCreateParams &Params)
{
    // call base class first!!!!!!!!!!
    TForm::CreateParams(Params);

    // tell frmSetupMain to minimize to the taskbar when minimized
    Params.ExStyle |= WS_EX_APPWINDOW;
}
Hvor TForm2 her med FormStyle = fsNormal.
Så er den ordnet :-)

2:
Er en del sværere. Jeg har fundet følgende kode:
void __fastcall TForm2::WndProc(Messages::TMessage &Message)
{
if (Message.Msg==WM_SHOWWINDOW && !Message.WParam &&
  Message.LParam==SW_PARENTCLOSING)
      {
      Message.Result=true;
      }
else
  TForm::WndProc(Message);
}

Det virker, men er uhensigtsmæssigt af to grunde:
1. Form2 bliver sendt til baggrunden (og en BringToFront() efter Message.Result=true hjælper ikke på det.
2. Når man efter minimering trykker på programmets (hovedformens) knap i taskbaren, bliver denne ikke restoret, istedet bliver Form2 aktiveret. Man kan kun restore Form1 ved at højreklikke på dens knap og vælge restore.
Avatar billede borrisholt Novice
27. april 2001 - 13:09 #10
Jeg forstår ikke hvad problemet er ..... Jeg skrev det kode jeg viste dig i Delphi. Og det virker bare sådan. Dine ideer om at overstyre både det ene og det andet er slet ikke nødvendig. Bare gør som beskrevet, og vupti du er i luften. Sådan var det i Delphi så mon ikke det skulle være magen til i C++ Builder ....

Jens B
Avatar billede rasmusw Nybegynder
27. april 2001 - 13:29 #11
jeg gjorde som beskrevet, og det virker ikke uden den kode som jeg tilføjede.
har du prøvet at minimere Form1 i din applikation?
Avatar billede rasmusw Nybegynder
01. maj 2001 - 11:05 #12
Jens B: jeg har i mellemtiden også fundet ud af hvorfor din kode ikke virker ordentligt.
Det er fordi Owner og Parent ikke er NULL når man bare ændrer FormStyle. - Derfor bliver vinduet stadig minimeret med. På en MDI form er både Owner og Parent som standard formens MDI parent.
Så hvis man har Owner og Parent er man nødt til at overstyre WndProc.

Jeg har dog stadig ikke løst de to ovenstående problemer.
Avatar billede borrisholt Novice
02. maj 2001 - 23:55 #13
rasmusw  >> Nu har jeg kigget lidt mere på det ...

prøv det her det løser halvdelen ...


void __fastcall TForm2::CreateParams(TCreateParams &Params)
{
    // call base class first!!!!!!!!!!
    TForm::CreateParams(Params);

    // tell frmSetupMain to minimize to the taskbar when minimized
    Params.ExStyle |= WS_EX_APPWINDOW;
}


void __fastcall TForm2::WndProc(Messages::TMessage &Message)
{
if (Message.Msg==WM_SHOWWINDOW && Message.WParam==0 && Message.LParam==SW_PARENTCLOSING)
{
    Message.Result=true;
    SetWindowPos(Application->Handle,HWND_TOPMOST    ,0,0,0,0,SWP_SHOWWINDOW);
    SetWindowPos(Application->Handle,HWND_NOTOPMOST  ,0,0,0,0,SWP_SHOWWINDOW);
}
else
  TForm::WndProc(Message);
}

Så kan du minimer din hoved form, og lade dit MDI child stå. Men du kan stadig ikke komme til hoved formen ;-(
Avatar billede rasmusw Nybegynder
04. maj 2001 - 11:23 #14
jeg har rettet lidt i ovenstående kode:
  SetWindowPos(this->Handle,HWND_NOTOPMOST  ,this->Left,this->Top,this->Width,this->Height,SWP_NOZORDER);
  SetWindowPos(this->Handle,HWND_TOPMOST    ,this->Left,this->Top,this->Width,this->Height,SWP_SHOWWINDOW);

Bemærk SWP_NOZORDER på det første SetWindowPos kald og at jeg i stedet for Application->Handle har brugt this->Handle, dvs. formens egen handle.

Ellers ville det ikke virke her.
Avatar billede borrisholt Novice
04. maj 2001 - 11:24 #15
Virker det hele så ?
Avatar billede rasmusw Nybegynder
04. maj 2001 - 11:25 #16
orv, ja. jeg glemte at jeg også havde rettet på størrelsesangivelserne for at vinduet ikke skulle blive en lille klat i øverste venstre hjørne af skærmen, men det er nok kun nødvendigt fordi jeg ændrede vindues-handlet.
Nu bliver vinduet liggende øverst, men inaktivt. Det er jeg ret sikker på skyldes at applikationen siger til windows at hovedformen er blevet minimeret og derfor giver windows kontrollen videre til den sidst aktive applikation.
Avatar billede rasmusw Nybegynder
04. maj 2001 - 11:25 #17
jeg deler lige pointene ud.
Avatar billede rasmusw Nybegynder
04. maj 2001 - 11:27 #18
det virker ikke optimalt - man kan stadig ikke komme til hovedformen, men det må jeg så leve med indtil videre, og jeg har også fundet ud af at man bliver nødt til at lave en ny kopi af det oprindelige vindue når man ændrer FormStyle, fordi ellers sker der rent faktisk sjove ting. - F.eks. hvis man har lavet ændringer i vindues-menuen, så mister man dem ved ændring af FormStyle.
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