C ++ GUI кнопка застряла внизу - PullRequest
0 голосов
/ 13 февраля 2019

Я делаю форму C ++ GUI для своей матери в windows.h, и я не могу понять, как заставить кнопки «adaugare», «iesire», «refresh» и т. Д. Придерживаться нижней частиокна формы.Я хочу сделать так, чтобы они автоматически перемещались при изменении размера формы, чтобы они всегда были справа внизу.Пожалуйста, помогите мне, ребята, потому что я новичок в C ++ Gui!

#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif

#include <tchar.h>
#include <windows.h>
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>

using namespace std;

ofstream fout;
ifstream fin;
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

HWND hwnd;               /* This is the handle for our window */
HWND button[5];
HWND banda[100];
HWND tip[100];
HWND lungime[100];
HWND latime[100];
HWND data1[100];
HWND button_valideaza[100];

int button_index[100];

int i = 0, counter = 1;
char buffer[10];
char textEP[20];
char textTip[20];
char textLungime[20];
char textLatime[20];
char textData[20];
char textAll[101];




/*  Make the class name into a global variable  */
TCHAR szClassName[] = _T("CodeBlocksWindowsApp");


int getIndex(){

fin.open("record.txt", std::ios_base::in);
string line1;
string line;
while(getline(fin, line1)) {
    line = line1;
}
char save[line.size()];
strcpy(save, line.c_str());
char *p = strtok(save, " ");
fin.close();

return atoi(p);
}

void refresh() {

}


int WINAPI WinMain(HINSTANCE hThisInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpszArgument,
                   int nCmdShow)
{

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 */
        _T("Flux Artego"),       /* Title Text */
        WS_OVERLAPPEDWINDOW, /* default window */
        CW_USEDEFAULT,       /* Windows decides the position */
        CW_USEDEFAULT,       /* where the window ends up on the screen */
        700,                 /* The programs width */
        300,                 /* 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()  */

void scrie() {
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
WORD cmd = LOWORD(wParam);
switch (message)                  /* handle the messages */
{
    case WM_CREATE:   // fac butoane, label etc

        counter = getIndex();
        counter++;
        fout.open("record.txt", std::ios_base::app);
        std::fill_n(button_index, 100, -1);

        button[0] = CreateWindow("BUTTON",
                                 "Iesire",
                                 WS_VISIBLE | WS_CHILD | WS_BORDER,
                                 560, 220, 100, 20,
                                 hwnd, (HMENU)1, NULL, NULL);   // (HMENU) 1 reprezinta care case din switch se executa
        button[1] = CreateWindow("BUTTON",
                                 "Adauga",
                                 WS_VISIBLE | WS_CHILD | WS_BORDER,
                                 450, 220, 100, 20,
                                 hwnd, (HMENU)2, NULL, NULL);

        button[2] = CreateWindow("BUTTON",
                                 "Refresh",
                                 WS_VISIBLE | WS_CHILD | WS_BORDER,
                                 340, 220, 100, 20,
                                 hwnd, (HMENU)3, NULL, NULL);


        break;

    case WM_COMMAND:  // fac instructiuni butoane
        switch (cmd)
        {
            case 1:
                //::MessageBeep(MB_ICONERROR);
                //::MessageBox(hwnd, "Ai salvat ?", "atentie", MB_OKCANCEL);
                cout << "GoodBye!";
                PostQuitMessage(0);
                break;

            case 2:   // Adaug nou record

                banda[i] = CreateWindow("EDIT",
                                        "EP",
                                        WS_BORDER | WS_CHILD | WS_VISIBLE,
                                        20, 30 * i, 30, 25,
                                        hwnd, NULL, NULL, NULL);
                tip[i] = CreateWindow("EDIT",
                                      "100",
                                      WS_BORDER | WS_CHILD | WS_VISIBLE,
                                      55, 30 * i, 100, 25,
                                      hwnd, NULL, NULL, NULL);
                lungime[i] = CreateWindow("EDIT",
                                          "Lungime",
                                          WS_BORDER | WS_CHILD | WS_VISIBLE,
                                          160, 30 * i, 100, 25,
                                          hwnd, NULL, NULL, NULL);
                latime[i] = CreateWindow("EDIT",
                                         "Latime",
                                         WS_BORDER | WS_CHILD | WS_VISIBLE,
                                         265, 30 * i, 100, 25,
                                         hwnd, NULL, NULL, NULL);

                data1[i] = CreateWindow("EDIT",
                                        "Data",
                                        WS_BORDER | WS_CHILD | WS_VISIBLE,
                                        370, 30 * i, 100, 25,
                                        hwnd, NULL, NULL, NULL);
                button_valideaza[i] = CreateWindow("BUTTON",
                                                   "Scrie",
                                                   WS_VISIBLE | WS_CHILD | WS_BORDER,
                                                   475, 30 * i, 80, 20,
                                                   hwnd, (HMENU)(i+5), NULL, NULL);
                i++;
                break;
            case 3:         // Refresh

                refresh();

                break;
            case 4:         // Compute
                break;
            default:
                if (cmd > 4 && cmd < 103)
                {
                    int index;
                    if (button_index[cmd-3] == -1){   // daca buton index nu a fost setata
                        button_index[cmd-3] = counter;
                        index = counter;
                        //cout << "Prima apasare a butinului " << cmd-3 << " si primeste index "<<counter<<endl;
                        counter++;
                    } else {                       // a fost setat
                        index = button_index[cmd-3];
                        //cout << "Deja apasat butonul "<< cmd-3 << " si are vechiul index " << button_index[cmd-3] << endl;
                        ::MessageBox(hwnd, "Pentru a rescrie apasa pe REFRESH","Suprascriere", MB_OK);
                    }

                    int gwtstat = 0;
                    gwtstat = GetWindowText(banda[cmd-5], &textEP[0], 20);
                    gwtstat = 0;
                    gwtstat = GetWindowText(tip[cmd-5], &textTip[0], 20);
                    gwtstat = 0;
                    gwtstat = GetWindowText(lungime[cmd-5], &textLungime[0], 20);
                    gwtstat = 0;
                    gwtstat = GetWindowText(latime[cmd-5], &textLatime[0], 20);
                    gwtstat = 0;
                    gwtstat = GetWindowText(data1[cmd-5], &textData[0], 20);
                    itoa(index, buffer, 10);
                    strcpy(textAll, buffer);
                    strcat(textAll," ");
                    strcat(textAll,textEP);
                    strcat(textAll, " ");
                    strcat(textAll,textTip);
                    strcat(textAll, " ");
                    strcat(textAll, textLungime);
                    strcat(textAll, " ");
                    strcat(textAll, textLatime);
                    strcat(textAll, " ");
                    strcat(textAll, textData);
                    fout << textAll << "\n";
                    ::MessageBox(hwnd, textAll,"text", MB_OKCANCEL);

                }
                break;
        }

        break;
    case WM_DESTROY:
        fout.close();
        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;
}

1 Ответ

0 голосов
/ 13 февраля 2019

К сожалению, нет механизма для этого автоматически.Вы должны написать код, который прослушивает события определения размера, вычисляет соответствующий размер и позицию каждого элемента управления и перемещает его соответствующим образом.Это довольно просто, если вы понимаете этот процесс, но это довольно трудоемкий процесс, особенно если вам нужно настроить большое количество элементов управления.

Начните с добавления обработчика для сообщения WM_SIZE в свой основной файл.процедура окна окна.Это сообщение отправляется при изменении размера окна.

Внутри этого обработчика вы будете вызывать функцию MoveWindow или SetWindowPos, чтобы изменить положение ваших дочерних окон (т. Е. Элементов управления; т.е., ваши кнопки).

Вот пример кода:

case WM_SIZE:
{
    const int cxPadding = 12;
    const int cyPadding = 12;

    // Get client rectangle for parent window.
    RECT rcParent;
    GetClientRect(hwnd, &rcParent);

    RECT rcButton[5];

    // Adjust the position of the first button.
    // It will be the furthest one to the right.
    GetClientRect(button[0], &rcButton[0]);
    SetWindowPos(button[0],
                 NULL,
                 (rcParent.right  - cxPadding - (rcButton[0].right  - rcButton[0].left)),
                 (rcParent.bottom - cyPadding - (rcButton[0].bottom - rcButton[0].top)),
                 0,
                 0,
                 SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);

    // Adjust the position of the second button.
    // It will be the next to the first one.
    GetClientRect(button[1], &rcButton[1]);
    SetWindowPos(button[1],
                 NULL,
                 (rcParent.right  - cxPadding - (rcButton[0].right  - rcButton[0].left)
                                  - cxPadding - (rcButton[1].right  - rcButton[1].left)),
                 (rcParent.bottom - cyPadding - (rcButton[1].bottom - rcButton[1].top)),
                 0,
                 0,
                 SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);

    // etc.
}

Чтобы уменьшить мерцание при перемещении большого количества дочерних элементов управления, вы можете использовать функцию DeferWindowPos.Это требует, чтобы вы сначала вызывали BeginDeferWindowPos, затем вызывали DeferWindowPos (точно так же, как SetWindowPos) для каждого элемента управления, а затем, наконец, вызывали EndDeferWindowPos, когда вы закончите настройку всех элементов управления.См. В чем смысл DeferWindowPos? в блоге Рэймонда Чена.

Кроме того, если вы пытаетесь изучать программирование для Windows API, сделайте себе огромное одолжение и возьмите копию классического произведения Чарльза Петцольда.книга, Программирование Windows (5-е издание) .Да, вам нужно 5-е издание.Более новые издания охватывают другой язык программирования / рамки.Вы можете найти использованные копии на Amazon.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...