Бортовой журнал Ктулху

Простое оконное приложение на WinAPI и C++

Когда подсаживаешься на C++, очень сложно остановиться. Мне показалось мало просто написать какое-нибудь простое приложение под Linux, я сразу решил его делать и под Windows. 

Итак, задача на данный момент - написать пока что простое оконное приложение с необходимыми элементами управления пока без функционала на чистом WinAPI на языке C++.

Мне нравится классические Windows приложения, такие, как они выглядели в старых Windows 98/2000/XP. В идеале, чтобы мое приложение запускалось на 2000+.

И, конечно же, я пишу приложение, которое смогу использовать в работе. 

Как и предыдущий менеджер http запросов, этот будет уметь делать POST на указанный URL.

Но, постойте ка.

1446654191191666455

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

Да и зачем писать приложение на C++, если есть Java, куча разных кроссплатформенных фреймворков типа Electron?

Но в том то и дело, что мне интересно отойти от принципа "вжух-вжух и в продакшен" и писать нечто под определенную ОС.

Пусть программа будет одна под Windows, другая под Linux, третья под Mac, но я буду знать из чего оно состоит. В конце концов, каждый программист пишет тонну хеллоуворлдов, у меня будет такой.

Тогда, начнем.

Это будет первая часть, посвященная графической оболочке.

 2021 06 07 15 18 56

Это аналог простого окна на GTK но уже под Windows.

Как и в предыдущем примере, не буду приводить весь код, выложу ссылку на гитхаб, но покажу основные компоненты.

Главная функция аналогичная main() - WinMain

 
int CALLBACK WinMain(
  _In_ HINSTANCE hInstance,
  _In_opt_ HINSTANCE hPrevInstance,
  _In_ LPSTR lpCmdLine,
  _In_ int nCmdShow
) {
  // Иконка приложения
  LPCTSTR iconPathName = L "work.ico";
  UINT icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE;
  HANDLE hIcon = LoadImage(hInstance, iconPathName, IMAGE_ICON, 0, 0, icon_flags);
  WNDCLASSEX wcex;
// инициализация параметров 
  wcex.cbSize = sizeof(WNDCLASSEX);
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = WndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = hInstance;
  wcex.hIcon = (HICON) hIcon; // set icon
  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wcex.lpszMenuName = NULL;
  wcex.lpszClassName = szWindowClass;
  wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
 
  if (!RegisterClassEx( & wcex)) {
    MessageBox(NULL,
      _T("Call to RegisterClassEx failed!"),
      _T("Windows Desktop Guided Tour"),
      NULL);
 
    return 1;
  }
 
  // Store instance handle in our global variable
  hInst = hInstance;
 
  HWND hWnd = CreateWindow(
    szWindowClass,
    szTitle,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT,
    800, // width
    500, // height
    NULL,
    NULL,
    hInstance,
    NULL
  );
 
  if (!hWnd) {
    MessageBox(NULL,
      _T("Call to CreateWindow failed!"),
      _T("Windows Desktop Guided Tour"),
      NULL);
 
    return 1;
  }
 
  ShowWindow(hWnd,
    nCmdShow);
  UpdateWindow(hWnd);
 
  // Main message loop:
  MSG msg;
  while (GetMessage( & msg, NULL, 0, 0)) {
    TranslateMessage( & msg);
    DispatchMessage( & msg);
  }
 
  return (int) msg.wParam;
}

Вторая функция WndProc является обработчиком (насколько я понял).

 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 PAINTSTRUCT ps;
 HDC hdc;
 TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message)
{
 case WM_CREATE:
break;
case WM_COMMAND:
break;
case WM_PAINT:
 
 break;
 
 case WM_DESTROY:
 PostQuitMessage(0);
 break;
default:
 return DefWindowProc(hWnd, message, wParam, lParam);
 break;
 }
return 0;
}

Для начала пока достаточно. 

https://github.com/kotulhu/ExamleWindowsApp/blob/main/main.cpp