Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Exemplen i det här avsnittet beskriver hur du utför följande uppgifter:
- Skapa ett huvudfönster
- Skapa, räkna upp och ändra storlek på underordnade fönster
- förstör ett fönster
- Att använda Layered Windows
Skapa ett huvudfönster
Det första fönstret som ett program skapar är vanligtvis huvudfönstret. Du skapar huvudfönstret med hjälp av funktionen CreateWindowEx, som anger fönsterklass, fönsternamn, fönsterformat, storlek, position, menyhandtag, instanshandtag och skapandedata. Ett huvudfönster tillhör en programdefinierad fönsterklass, så du måste registrera fönsterklassen och ange en fönsterprocedur för klassen innan du skapar huvudfönstret.
De flesta program använder vanligtvis WS_OVERLAPPEDWINDOW formatmall för att skapa huvudfönstret. Det här formatet ger fönstret ett namnlist, en fönstermeny, en storlekskantlinje och minimerar och maximerar knappar. Funktionen CreateWindowEx returnerar ett handtag som unikt identifierar fönstret.
I följande exempel skapas ett huvudfönster som tillhör en programdefinierad fönsterklass. Fönstrets namn, Huvudfönster, visas i fönstrets namnlist. Genom att kombinera formatmallarna WS_VSCROLL och WS_HSCROLL med WS_OVERLAPPEDWINDOW formatmallen skapar programmet ett huvudfönster med vågräta och lodräta rullningslister utöver de komponenter som tillhandahålls av WS_OVERLAPPEDWINDOW formatmallen. De fyra förekomsterna av CW_USEDEFAULT konstant anger fönstrets ursprungliga storlek och position till de systemdefinierade standardvärdena. Genom att ange NULL- i stället för ett menyhandtag har fönstret menyn definierad för fönsterklassen.
HINSTANCE hinst;
HWND hwndMain;
// Create the main window.
hwndMain = CreateWindowEx(
0, // no extended styles
"MainWClass", // class name
"Main Window", // window name
WS_OVERLAPPEDWINDOW | // overlapped window
WS_HSCROLL | // horizontal scroll bar
WS_VSCROLL, // vertical scroll bar
CW_USEDEFAULT, // default horizontal position
CW_USEDEFAULT, // default vertical position
CW_USEDEFAULT, // default width
CW_USEDEFAULT, // default height
(HWND) NULL, // no parent or owner window
(HMENU) NULL, // class menu used
hinst, // instance handle
NULL); // no window creation data
if (!hwndMain)
return FALSE;
// Show the window using the flag specified by the program
// that started the application, and send the application
// a WM_PAINT message.
ShowWindow(hwndMain, SW_SHOWDEFAULT);
UpdateWindow(hwndMain);
Observera att föregående exempel anropar funktionen ShowWindow när huvudfönstret har skapats. Detta görs eftersom systemet inte automatiskt visar huvudfönstret när det har skapats. Genom att skicka flaggan SW_SHOWDEFAULT till ShowWindowtillåter programmet att programmet som startade programmet anger det inledande visningstillståndet för huvudfönstret. Funktionen UpdateWindow skickar fönstret sitt första WM_PAINT meddelande.
Skapa, räkna upp och ändra storlek på underordnade fönster
Du kan dela upp ett fönsters klientområde i olika funktionella områden med hjälp av underordnade fönster. Att skapa ett underordnat fönster är som att skapa ett huvudfönster– du använder funktionen CreateWindowEx. Om du vill skapa ett fönster i en programdefinierad fönsterklass måste du registrera fönsterklassen och ange en fönsterprocedur innan du skapar det underordnade fönstret. Du måste ge det underordnade fönstret formatet WS_CHILD och ange ett överordnat fönster för det underordnade fönstret när du skapar det.
I följande exempel delas klientområdet i ett programs huvudfönster in i tre funktionella områden genom att tre underordnade fönster med samma storlek skapas. Varje underordnat fönster har samma höjd som huvudfönstrets klientområde, men är en tredjedel av dess bredd. Huvudfönstret skapar de underordnade fönstren som svar på det WM_CREATE meddelandet, som huvudfönstret tar emot under sin egen fönsterskapandeprocess. Eftersom varje underordnat fönster har WS_BORDER formatmall har var och en en tunn linjekantlinje. Dessutom, eftersom stilen WS_VISIBLE inte har angetts, är varje underordnat fönster initialt dolt. Observera också att varje underordnat fönster tilldelas en identifikator för underordnade fönster.
Huvudfönstret ändrar storlek och positionerar de underordnade fönstren som svar på meddelandet WM_SIZE, vilket huvudfönstret tar emot när dess storlek ändras. Som svar på WM_SIZEhämtar huvudfönstret dimensionerna för klientområdet med hjälp av funktionen GetClientRect och skickar sedan dimensionerna till funktionen EnumChildWindows. EnumChildWindows skickar handtaget för varje underordnat fönster i tur och ordning till den programdefinierade EnumChildProc återuppringningsfunktionen. Den här funktionen storleksanpassar och placerar varje underordnat fönster genom att anropa funktionen MoveWindow. storleken och positionen baseras på dimensionerna för huvudfönstrets klientområde och identifieraren för det underordnade fönstret. Efteråt anropar EnumChildProc funktionen ShowWindow för att göra fönstret synligt.
#define ID_FIRSTCHILD 100
#define ID_SECONDCHILD 101
#define ID_THIRDCHILD 102
LONG APIENTRY MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RECT rcClient;
int i;
switch(uMsg)
{
case WM_CREATE: // creating main window
// Create three invisible child windows.
for (i = 0; i < 3; i++)
{
CreateWindowEx(0,
"ChildWClass",
(LPCTSTR) NULL,
WS_CHILD | WS_BORDER,
0,0,0,0,
hwnd,
(HMENU) (int) (ID_FIRSTCHILD + i),
hinst,
NULL);
}
return 0;
case WM_SIZE: // main window changed size
// Get the dimensions of the main window's client
// area, and enumerate the child windows. Pass the
// dimensions to the child windows during enumeration.
GetClientRect(hwnd, &rcClient);
EnumChildWindows(hwnd, EnumChildProc, (LPARAM) &rcClient);
return 0;
// Process other messages.
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
LPRECT rcParent;
int i, idChild;
// Retrieve the child-window identifier. Use it to set the
// position of the child window.
idChild = GetWindowLong(hwndChild, GWL_ID);
if (idChild == ID_FIRSTCHILD)
i = 0;
else if (idChild == ID_SECONDCHILD)
i = 1;
else
i = 2;
// Size and position the child window.
rcParent = (LPRECT) lParam;
MoveWindow(hwndChild,
(rcParent->right / 3) * i,
0,
rcParent->right / 3,
rcParent->bottom,
TRUE);
// Make sure the child window is visible.
ShowWindow(hwndChild, SW_SHOW);
return TRUE;
}
Förstöra ett fönster
Du kan använda funktionen DestroyWindow för att förstöra ett fönster. Vanligtvis skickar ett program WM_CLOSE meddelandet innan ett fönster förstörs, vilket ger fönstret möjlighet att uppmana användaren att bekräfta innan fönstret förstörs. Ett fönster som innehåller en fönstermeny tar automatiskt emot WM_CLOSE meddelande när användaren klickar på Stäng från fönstermenyn. Om användaren bekräftar att fönstret ska förstöras anropar programmet DestroyWindow. Systemet skickar meddelandet WM_DESTROY till fönstret när det har tagits bort från skärmen. Som svar på WM_DESTROYsparar fönstret sina data och frigör alla resurser som det allokerade. Ett huvudfönster avslutar bearbetningen av WM_DESTROY genom att anropa funktionen PostQuitMessage för att avsluta programmet.
I följande exempel visas hur du frågar efter användarbekräftelse innan du förstör ett fönster. Som svar på WM_CLOSEvisas en dialogruta som innehåller Ja, Nejoch Avbryt knappar. Om användaren klickar på Jaanropas DestroyWindow. annars förstörs inte fönstret. När programmet hanterar WM_CLOSE-meddelandet returneras 0 i alla fall. Eftersom fönstret som förstörs är ett huvudfönster anropar exemplet PostQuitMessage som svar på WM_DESTROY.
case WM_CLOSE:
// Create the message box. If the user clicks
// the Yes button, destroy the main window.
if (MessageBox(hwnd, szConfirm, szAppName, MB_YESNOCANCEL) == IDYES)
DestroyWindow(hwndMain);
return 0;
case WM_DESTROY:
// Post the WM_QUIT message to
// quit the application terminate.
PostQuitMessage(0);
return 0;
Använda skiktade Windows
Om du vill att en dialogruta ska visas som ett genomskinligt fönster skapar du först dialogrutan som vanligt. På WM_INITDIALOGanger du sedan den skiktade biten av fönstrets utökade formatmall och anropar SetLayeredWindowAttributes med önskat alfavärde. Koden kan se ut så här:
// Set WS_EX_LAYERED on this window
SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// Make this window 70% alpha
SetLayeredWindowAttributes(hwnd, 0, (255 * 70) / 100, LWA_ALPHA);
Observera att den tredje parametern i SetLayeredWindowAttributes är ett värde som sträcker sig från 0 till 255, där 0 gör fönstret helt transparent och 255 gör det helt ogenomskinligt. Den här parametern efterliknar den mer mångsidiga BLENDFUNCTION- för funktionen AlphaBlend.
Om du vill göra det här fönstret helt ogenomskinlig igen tar du bort den WS_EX_LAYERED biten genom att anropa SetWindowLong och be sedan fönstret att måla om. Att ta bort biten är att låta systemet veta att det kan frigöra lite minne som är associerat med skiktning och omdirigering. Koden kan se ut så här:
// Remove WS_EX_LAYERED from this window styles
SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
// Ask the window and its children to repaint
RedrawWindow(hwnd,
NULL,
NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
För att kunna använda underordnade fönster i lager måste programmet deklarera sig som medveten om Windows 8 i manifestet.
För Windows 10/11 kan man inkludera det här kompatibilitetsfragmentet i sitt app.manifest för att få den att känna igen Windows 10.
...
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 GUID -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
...
Mer information om hur du ändrar appmanifest finns här: Programmanifest