Diskuze: Prosim o radu Menu pripnout
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Vlasta Mozny:23.1.2017 19:41
Omlouvam se nejde mi editovat tak to postnu znova
Potreboval bych tohle menu
switch (message) /* handle the messages */
{
case WM_CREATE:{
HMENU hMenuBar = CreateMenu();
HMENU hFile = CreateMenu();
HMENU hOption = CreateMenu();
HMENU hEdit = CreateMenu();
HMENU hAbout = CreateMenu();
AppendMenu (hMenuBar,MF_POPUP, (UINT_PTR)hFile ,"File");
AppendMenu (hMenuBar,MF_POPUP,(UINT_PTR)hOption,"Options");
AppendMenu (hMenuBar,MF_POPUP,(UINT_PTR)hEdit,"Edit");
AppendMenu (hMenuBar,MF_POPUP,(UINT_PTR)hAbout,"About");
AppendMenu (hFile,MF_STRING,NULL,"Exit");
AppendMenu (hEdit,MF_STRING,NULL,"Zmena Jmena");
AppendMenu (hOption,MF_STRING,NULL,"Obtiznost");
AppendMenu (hOption,MF_STRING,NULL,"Vysledky");
AppendMenu (hAbout,MF_STRING,NULL,"O me");
SetMenu (hwnd, hMenuBar);
break;
}
Pripnout k tomuhle kodu
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HWND textfield , button ; // hwdn je prirazeni prikazu pro okno . textfield je ze muzeme do okna psat . a button je vytvoreni tlacitka ve spodni casti prirazujeme parametry
/* Make the class name into a global variable */
char szClassName[ ] = ("Okenka");
char textSaved [20];
HWND TextBox;
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Gambling", /* Title Text */
WS_MINIMIZEBOX | WS_SYSMENU, // nastaveno minimalizovani a windows menu
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
500, /* The programs width */
500, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
textfield = CreateWindow ("STATIC",
"Ahoj lidicky prvni okno",
WS_VISIBLE | WS_CHILD | WS_BORDER,
175,120,150,20, //Prvni vzdalenost od kraje druhe je vzdalenost od horniho okraje posledni treti delka a ctvrta sirka ramecku nebo zorneho pole
hwnd,NULL,NULL,NULL);
button = CreateWindow ("BUTTON",
"Error",
WS_VISIBLE | WS_CHILD | WS_BORDER,
220,150,60,40,
hwnd,(HMENU) 1,NULL,NULL); // NULL budou pokud nic necheme delat jinak pak se NULL meni na urcite veci co chceme pridelit trema na Hmenu ktere prideluje case
button = CreateWindow ("BUTTON",
"Close",
WS_VISIBLE | WS_CHILD | WS_BORDER,
220,410,60,40,
hwnd,(HMENU) 2,NULL,NULL);
TextBox = CreateWindow ("EDIT",
"", // prednastavis text v psacim oknu
WS_BORDER | WS_CHILD | WS_VISIBLE,
10,10,400,20,
hwnd,NULL ,NULL ,NULL);
CreateWindow ("BUTTON",
"GO",
WS_VISIBLE | WS_CHILD | WS_BORDER,
420,10,70,20,
hwnd,(HMENU) 3,NULL,NULL);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 1:
::MessageBeep(MB_ICONERROR);
::MessageBox(hwnd,"Neco je spatne","Chyba", MB_OK ); // prvni je nazev okna druhe je hlaska v okne
break;
case 2:
PostQuitMessage (0); // tohele ukno ukonci okno
case 3:
int gwtstat =0;
//char *t = &textSaved[0];
gwtstat = GetWindowText (TextBox, &textSaved [0], 20);
::MessageBox (hwnd,textSaved,"Hlaskove okno",MB_OK);
::MessageBeep (MB_DEFBUTTON1);
if (gwtstat == 0)
{
//promt to enter text again
}
}
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
Radek Chalupa:24.1.2017 6:37
Především bych doporučoval vytvářet menu v resource skriptu, každé
slušné vývojové prostředí pro windows desktop by mělo mít "vizuální"
resource editor. A MS Visual Studio community edice je jasnou volbou.
Vytváření menu v kódu má smysl v případech že hi generuješ dynamicky,
např. seznam posledních souborů
atd..
Nicméně v tom kódu bude problém v tom, že nastavuješ oknu menu v obsluze
WM_CREATE, tipoval bych že v daném okamžiku ještě není handle okna platné
(to až po vrácení zprávy WM_CREATE).
V obsluze WM_COMMAND je LOWORD(wparam) tzv. id položky (tj. nějaké číslo
přiřazené položce v resource skriptu nebo při dynamickém vytvoření.
Ještě v tom kódu vidím chybu v ukončení okna pomocí postQuitMessage.
Tahle funkce natvrdo ukončí celou smyčku zpráv a měla by se zavolat jedině
a pouze v obsluze WM_DESTROY. Když chceš zavřít okno dynamicky, použij
PostMessage(hwnd, WM_CLOSE, 0,0), což způsobí že všechny možnosti
zavření okna jsou přes obsluhu WM_CLOSE, kde můžeš např. uložit nějaké
nastavení apod.
Radek Chalupa
- individuální konzultace, školení programování, (C/C++, C#, WinAPI, .NET, COM, ATL, MFC...)
- vývoj software na zakázku
Vlasta Mozny:24.1.2017 7:40
Diky za radu to WS_close se mi bude hodit opravdu vice kazdopadne chtel sem prejit na wxWidgetds projekt ale nedari se mi zprovoznit prostredi celou noc tu instaluji knihovny dokola .jinak k tomu HWND jde teda nejak nahradit to WM_create ze by v tom bylo jen Menu a button a dalsi veci v necim jinym ?
Radek Chalupa:24.1.2017 7:50
Samozřejmě pokud máš (správně) vytvořené (nebo načtené z resource)
handle menu, tak můžeš použít fci SetMenu kdykoliv poté co ti
CreateWindow(Ex) vrátí handle vytvořeného okna.
Pokud hodláš používat wxwidgets, tak to je kompletní framework se svojí
logikou obsluhy událostí atd. V každém případě se ale vyplatí znát
alespoň základní principy fungování WinAPI (zprávy, procedura okna,
smyčka zpráv..), všechny frameworky (včetně .NET) jsou postavené nad
WinAPI..
Radek Chalupa
- individuální konzultace, školení programování, (C/C++, C#, WinAPI, .NET, COM, ATL, MFC...)
- vývoj software na zakázku
Zobrazeno 6 zpráv z 6.