26. april 2001 - 18:54Der 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.
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 !
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;
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.
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.
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: 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.
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.
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.
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.
Synes godt om
Ny brugerNybegynder
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.