[C/C++] Gui WinApi

Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
999
Реакции[?]
1,209
Поинты[?]
3K
году так 2010-2013(точно не помню) изучал STL, в частности, так называемые, "callback function". В параллели понадобилось что-то простое и быстрое для создания окна и базовых контролов, что бы не нужно было каждый раз городить код и что бы выглядело красиво. В конечном итоге родилась идея написать обертку над winapi, используя изучаемые в данный момент методы, завернув все в статическую библиотеку. Были написаны базовые методы, которые часто использовались мной в той или иной ситуации(от простого инжектора до корпоративных плагин-модулей). В скором времени дело было заброшено и случайно найдено на старой флешке уже "в наши дни") Возникла мысль слегка реанимировать старый проект и скинуть сюда с примерами его использования.

Что умеет(не все показано):


Дописывать полнофункциональный GUI нет смысла, так как готовых решений и так полно, а вот показать свою старую работу думаю стоит. Основные принципы работы кода это callback и лямбда функции, которые зачастую бывают полезными, а на фоне новых стандартов С++17 так вообще необходимы.

Пожалуйста, авторизуйтесь для просмотра ссылки.

Пожалуйста, авторизуйтесь для просмотра ссылки.


Подключаем как любое другое СДК. Библиотека собрана с использованием набора инструментов v141 в режиме MT.

Создаем проект "Приложение Window.exe", пустой. В настройках каталогов указываем пути к библиотеке(Lib и Include).
Создаем три фаила:
  • Base.cpp - точка входа
  • cMyWindow.cpp - описание методов класса
  • cMyWindow.h - список методов и свойств

cMyWindow.h создаем класс и подключаем библиотеку

Код:
#pragma once

#include <memory>
#include <algorithm>

 
#include <IWindow.hpp>
#pragma comment( lib, "WLib_x86.lib" )

class cMyWindow
{
public:
    cMyWindow(HINSTANCE hInstance);
    ~cMyWindow(void);
private:
    void OnCreate(void);
    std::unique_ptr<IWindow>   m_pWindow;
    
    HWND      m_hWnd;
    HINSTANCE m_hInstance;
};
cMyWindow.cpp описываем
Код:
#include "cMyWindow.h"
 
cMyWindow::cMyWindow(HINSTANCE hInstance)
                 : m_hInstance(hInstance)
{
  //создаем окно
    m_pWindow.reset(new IWindow(hInstance, "MyWindow_class", "DEMO::Window", 800, 600, m_hWnd));
    if (m_pWindow.get() != nullptr)
    {
         //если удалось создать объект, то работаем дальше
         OnCreate();
    }
}
void cMyWindow::OnCreate(void)
{
//тут будем создавать контролы и обработчики
}
cMyWindow::~cMyWindow()
{
//умные указатели, мусор сами почистят
}
Base.cpp описываем точку входа и создаем экземпляр нашего нового класса и запускаем обработку сообщений
Код:
#include"cMyWindow.h"
 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpszCommandLine, int iCommandShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpszCommandLine);
    UNREFERENCED_PARAMETER(iCommandShow);

    cMyWindow m_pDemoWindow(hInstance);
    MSG Msg = { 0 };
    while (GetMessage(&Msg, 0, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return Msg.wParam;
}
Собираем, запускаем, радуемся
 
Последнее редактирование:
В игре Source SDK
Забаненный
Статус
Оффлайн
Регистрация
10 Янв 2017
Сообщения
2,148
Реакции[?]
806
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Я тоже делал что-то подобное, но в 1 момент оно сломалось и я решил забросить)
 
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
999
Реакции[?]
1,209
Поинты[?]
3K
Пример простой кнопки и обработчика событий при клике:

Подключаем необходимые заголовки
Код:
#include <IButton.hpp>
#include <IUtility.hpp>
IButton.hpp содержит в себе методы для создания контрола Button
IUtility.hpp содержит в себе методы форматирования строк и метод вывода сообщения в консоль текущего треда. Для использования консоли ее нужно создать, прописав в точке входа:
Код:
AllocConsole();
    SetConsoleTitle("Debug");
Работаем в блоке OnCreate
Код:
void cMyWindow::OnCreate(void)
{ /*Пример простой кнопки и ее обработка*/
   new IButton(m_hWnd, "DEMO::IButton", 20, 30, 100, 30, [&](void)
   {
     IUtility::Log("Clicked DEMO::IButton\n" ); 
   }); }
new IButton(m_hWnd, /*дескриптор которому принадлежит контрол*/
"DEMO::IButton", /*текст*/
20, /*положение по оси X относительно (0,0) принадлежащего объекта*/
30, /*положение по оси Y относительно (0,0) принадлежащего объекта*/
100,/*ширина*/
30, /*высота*/
[&](void) //callback
{
IUtility::Log("Clicked DEMO::IButton\n"); /*Действие при клике*/
});



Второй способ создания кнопки(с возможностью управления ей)

Заводим указатель на объект IButton
Код:
std::unique_ptr<IButton>   m_pButton;
Создаем
Код:
/*Второй способ создания кнопки*/
    m_pButton.reset(new IButton(m_hWnd, "DEMO::IButton v2", 20, 70, 100, 30, [&](void)
    {
        IUtility::Log("Clicked DEMO::IButton v2\n");
    }));
теперь у нас есть возможность управлять этой кнопкой посредством указателя на нее m_pButton.
Доступ к методам класса можно получить с помощью конструкции std::unique_ptr::get
Для примера с помощью первой созданной кнопки изменим текст на второй и выставим ей флаг "Отключена":

Код:
/*Пример простой кнопки и ее обработка*/
    new IButton(m_hWnd, "DEMO::IButton", 20, 30, 100, 30, [&](void)
    {
        IUtility::Log("Clicked DEMO::IButton\n" );   
        
        static bool Status = true;
        Status ^= 1;

        
        m_pButton.get()->SetText( Status ?  "disabled" : "enabled");
        m_pButton.get()->SetEnable(Status);
        m_pButton.get()->SetTooltip("Подсказка");

    });
 
Последнее редактирование:
В игре Source SDK
Забаненный
Статус
Оффлайн
Регистрация
10 Янв 2017
Сообщения
2,148
Реакции[?]
806
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Всё конечно заебись
 
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
999
Реакции[?]
1,209
Поинты[?]
3K
TabControl:

подключаем:
Код:
#include <ITabControl.hpp>
объявляем указатель на объект:
Код:
std::unique_ptr<ITabControl> m_TabControl;
Создаем:
Код:
    m_TabControl.reset(new ITabControl(m_hWnd, 0, 0, 500, 500));
    m_TabControl.get()->AppendTab("DEMO::Tab1");
    m_TabControl.get()->AppendTab("DEMO::Tab2");
    m_TabControl.get()->AppendTab("DEMO::Tab3");
и перенесем ранее созданные кнопки в Tab1 и Tab2.
Код:
/*Пример простой кнопки и ее обработка*/
    new IButton(m_TabControl.get()->GetTab(0), "DEMO::IButton", 20, 30, 100, 30, [&](void)
    {
        IUtility::Log("Clicked DEMO::IButton\n" );   
        
        static bool Status = true;
        Status ^= 1;

        
        m_pButton.get()->SetText( Status ?  "disabled" : "enabled");
        m_pButton.get()->SetEnable(Status);
        m_pButton.get()->SetTooltip("Подсказка");

    });

    /*Второй способ создания кнопки*/
    m_pButton.reset(new IButton(m_TabControl.get()->GetTab(1), "DEMO::IButton v2", 20, 70, 100, 30, [&](void)
    {
        IUtility::Log("Clicked DEMO::IButton v2\n");
    }));
думаю понятно все)) Просто передаем контролу дескриптор, который мы получаем по Id таба, и передаем в конструктор нужного контрола. Заметьте: после этого расчет координат контролов будет отчитываться от (0,0) TabControl, а не формы
 
Участник
Статус
Оффлайн
Регистрация
25 Апр 2017
Сообщения
502
Реакции[?]
156
Поинты[?]
0
Так как я не обладают умом и сообразительностью ,спрошу,зачем это поебота нужна?
 
Пользователь
Статус
Оффлайн
Регистрация
15 Июн 2017
Сообщения
82
Реакции[?]
46
Поинты[?]
0
Так как я не обладаю умом и сообразительностью ,спрошу,зачем это поебота нужна?
Что бы у пользователя программы был свой пользовательский интерфейс , написанный на c++
 
Забаненный
Статус
Оффлайн
Регистрация
8 Май 2017
Сообщения
228
Реакции[?]
114
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Уф, выглядит неплохо. Развивай и лей на гитхаб. Есть возможность натягивать свои темы на оформление?
 
В игре Source SDK
Забаненный
Статус
Оффлайн
Регистрация
10 Янв 2017
Сообщения
2,148
Реакции[?]
806
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сверху Снизу