NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
IT rekvalifikace s podporou uplatnění. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!

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.

Aktivity
Avatar
Vlasta Mozny
Člen
Avatar
Vlasta Mozny:23.1.2017 19:36

Nemohl by mi nekdo poradit jak pripojit tohle menu

#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;
}
Editováno 23.1.2017 19:39
Odpovědět
23.1.2017 19:36
„Pokud chcete, aby vás měli za lháře, vždy říkejte pravdu.“
Avatar
Vlasta Mozny
Člen
Avatar
Odpovídá na Vlasta Mozny
Vlasta Mozny:23.1.2017 19:41

Omlouvam se nejde mi editovat tak to postnu znova

Nahoru Odpovědět
23.1.2017 19:41
„Pokud chcete, aby vás měli za lháře, vždy říkejte pravdu.“
Avatar
Vlasta Mozny
Člen
Avatar
Vlasta Mozny:23.1.2017 19:42

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;
}
Nahoru Odpovědět
23.1.2017 19:42
„Pokud chcete, aby vás měli za lháře, vždy říkejte pravdu.“
Avatar
Odpovídá na Vlasta Mozny
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

http://www.radekchalupa.cz

 
Nahoru Odpovědět
24.1.2017 6:37
Avatar
Vlasta Mozny
Člen
Avatar
Odpovídá na Radek Chalupa
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 ?

Nahoru Odpovědět
24.1.2017 7:40
„Pokud chcete, aby vás měli za lháře, vždy říkejte pravdu.“
Avatar
Odpovídá na Vlasta Mozny
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

http://www.radekchalupa.cz

 
Nahoru Odpovědět
24.1.2017 7:50
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.