Консультация № 195845
14.06.2019, 21:31
0.00 руб.
0 10 0
Здравствуйте! Прошу помощи в следующем вопросе:

как правильно составить заголовочные файлы?
я использую:
g++ (MinGW.org GCC-8.2.0-1) 8.2.0

есть файл main.cpp в нем код пример:
Код:
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AddMenu(HWND);

HMENU hMenu;

enum MENU {
NEW, OPEN, SAVE, SAVEAS, EXIT,
UNDO, REDO, COPY, PAST
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
HWND hMainWnd;
char szClassName[] = "MyClass";

WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc)){ MessageBox(NULL, "Cannot register class", "Error", MB_OK); return 0; }

//----------------------------
hMainWnd = CreateWindow(
szClassName,
"A Hello Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
600,
400,
(HWND)NULL,
hMenu,
(HINSTANCE)hInstance,
NULL
);
if(!hMainWnd){ MessageBox(NULL, "cannot crate main window", "error", MB_OK); return 0; }
//----------------------------

ShowWindow(hMainWnd, nCmdShow);
//UpdateWindow(hMainWnd);


MSG msg;
while (GetMessage(&msg, NULL, 0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
};

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
HDC hDC;
PAINTSTRUCT ps;
RECT rect;

switch (uMsg)
{
case WM_CREATE:
AddMenu(hWnd);
break;

case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, "HELLO WORLD", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;

case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

return 0;
};

void AddMenu(HWND hWnd){
hMenu = CreateMenu();

//FILE
HMENU hFileMenu = CreateMenu();
AppendMenu(hFileMenu, MF_STRING, MENU::NEW, "New \t ctrl+n");
AppendMenu(hFileMenu, MF_STRING, MENU::OPEN, "Open \t ctrl+o");
AppendMenu(hFileMenu, MF_STRING, MENU::SAVE, "Save \t ctrl+s");
AppendMenu(hFileMenu, MF_STRING, MENU::SAVEAS, "Save As...");
AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);//просто лини¤
AppendMenu(hFileMenu, MF_STRING, MENU::EXIT, "Exit \t alt+f4");
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, "File");

//EDIT
HMENU hEditMenu = CreateMenu();
AppendMenu(hEditMenu, MF_STRING, MENU::UNDO, "Undo");
AppendMenu(hEditMenu, MF_STRING, 2, "Redo");
AppendMenu(hEditMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hEditMenu, MF_STRING, 2, "Copy");
AppendMenu(hEditMenu, MF_STRING, 2, "Past");
AppendMenu(hEditMenu, MF_SEPARATOR, NULL, NULL);
//submenu
HMENU hEditSubMenu = CreateMenu();
AppendMenu(hEditSubMenu, MF_STRING, 12, "SubMenu Item1");
AppendMenu(hEditSubMenu, MF_STRING, 12, "SubMenu Item2");
AppendMenu(hEditSubMenu, MF_STRING, 12, "SubMenu Item3");
AppendMenu(hEditMenu, MF_POPUP, (UINT_PTR)hEditSubMenu, "Open SubMenu");

AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hEditMenu, "Edit");

//INFO
AppendMenu(hMenu, MF_STRING, NULL, "Info");

SetMenu(hWnd, hMenu);
};


вот теперь я его хочу разделить на файлы main.cpp WndProc.cpp и AddMenu.cpp, и соответственно для них нужно создать заголовочные файлы
WndProc.h, AddMenu.h, как правильно из написать и подключить в файле main.cpp

Обсуждение

давно
Посетитель
7438
7205
14.06.2019, 21:40
общий
Адресаты:
Напишите, что Вы хотите записать в файлы *.cpp
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
17042
808
15.06.2019, 06:51
общий
15.06.2019, 06:56
Адресаты:
Arthur, Вы знаете, писать код на чистом WinAPI под g++/MinGW - это, конечно, смело, но настолько утомительно, что я могу Вам только посочувствовать.

а)
Цитата: RSDN Magazine
WinAPI создавался для языка С, и имеет целый ряд недостатков в применении, как-то: невысокая безопасность, большой объем ручного кодирования для решения простейших задач, С-стиль, плохо выглядящий в C++-приложениях.

б) В качестве "точки входа" g++/MinGW ищет функцию main, ну или WinMain. А надо wWinMain. Кроме того, даже в случае правильной компиляции Вы рискуете не получить ничего, если не "поиграете" с флагами сборки. Для программирования на WinAPI "заточен" только Visual C++ (проект Win32 Application). Да и то, лучше используйте тогда не чистый WinAPI, а какой-нибудь фреймворк, например, MFC.Net: https://www.tutorialspoint.com/mfc/index.htm
Право, весь мир уже перешёл на визуальное проектирование, а Вы всё по старинке делать пытаетесь. Я Вам в этом очень сочувствую, потому что в иные годы сам таким был, но излечился. Пока Вы будете вручную одно окошко кодить, другой программист уже целое приложение нарисует при минимальном ручном коде.
в) Предположим, у Вас всё получилось, и каков результат? Приложение для одной и только одной операционной системы. Если уж используете g++, то смотрите в сторону, например, Qt - и легче, и приятнее, и разнообразнее.
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
давно
Посетитель
401281
56
15.06.2019, 19:09
общий
Адресаты:
Напишите, что Вы хотите записать в файлы *.cpp

в фале WndProc.cpp
Код:

#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
HDC hDC;
PAINTSTRUCT ps;
...
return 0;
};

в файле AddMenu.cpp
Код:

#include <windows.h>
void AddMenu(HWND hWnd){
hMenu = CreateMenu();
...
SetMenu(hWnd, hMenu);
};

а все остальное останица в майн файле, меня терзают сомнения надали писать #ifndef #endif, ну как то читал на сайте обучение с++ и там говорилось про то что если не проверять на повторное подключение то файл что то там два раза подключаются, ну с заголовочными файлами у меня туго
давно
Посетитель
401281
56
15.06.2019, 19:34
общий
Адресаты:
спасибо за столь информативный ответ, я новичок в с++
WinAPI создавался для языка СWinAPI создавался для языка С
это го я не знал,
Приложение для одной и только одной операционной системы. Если уж используете g++, то смотрите в сторону, например, Qt - и легче, и приятнее, и разнообразнее.
то есть я могу написать оконное приложение и скомпилировать его для виндовс и линукс не меняя код,ос,пк и компилятор?
давно
Старший Модератор
17042
808
16.06.2019, 19:46
общий
Адресаты:
Цитата: Arthur
то есть я могу написать оконное приложение и скомпилировать его для виндовс и линукс не меняя код,ос,пк и компилятор?


Да. Это называется кроссплатформенное программирование. Например, с использованием Qt / g++ Вы можете написать код для ОС: Linux, Windows, MacOS и даже Haiku. При этом C++ исходники будут идентичны (совместимость на уровне исходного кода), просто перекомпилируется исполняемый файл. Приложение будет выглядень и работать одинаково под перечисленными ОС.
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
давно
Старший Модератор
17042
808
16.06.2019, 19:50
общий
Адресаты:
Цитата: Arthur
надали писать #ifndef #endif,


Надо, в заголовочном файле. RTFM.
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
давно
Посетитель
401281
56
16.06.2019, 23:13
общий
Адресаты:
спасибо большое, очень помогли
давно
Старший Модератор
31795
6196
18.06.2019, 16:49
общий
Адресаты:
Цитата: Arthur
Андрей Кузнецов aka Dr_Andrew:
спасибо большое, очень помогли

Вам и отвечать.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401281
56
18.06.2019, 20:10
общий
Адресаты:
Вам и отвечать.

main.cpp
Код:
#include <windows.h>
#include "WndProc.h"

extern HMENU hMenu;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
HWND hMainWnd;
char szClassName[] = "MyClass";

WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)){ MessageBox(NULL, "Cannot register class", "Error", MB_OK); return 0; }

//----------------------------
hMainWnd = CreateWindow(
szClassName,
"A Hello Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
600,
400,
(HWND)NULL,
hMenu,
(HINSTANCE)hInstance,
NULL
);
if(!hMainWnd){ MessageBox(NULL, "cannot crate main window", "error", MB_OK); return 0; }
//----------------------------
ShowWindow(hMainWnd, nCmdShow);
//UpdateWindow(hMainWnd);

MSG msg;
while (GetMessage(&msg, NULL, 0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
};

TopMenu.h
Код:
#ifndef TOPMENU_H
#define TOPMENU_H

void AddMenu(HWND hWnd);

#endif TOPMENU_H

TopMenu.cpp
Код:
#include <windows.h>

HMENU hMenu;
enum MENU {
NEW, OPEN, SAVE, SAVEAS, EXIT,
UNDO, REDO, COPY, PAST
};

void AddMenu(HWND hWnd){
hMenu = CreateMenu();

//FILE
HMENU hFileMenu = CreateMenu();
AppendMenu(hFileMenu, MF_STRING, MENU::NEW, "New \t ctrl+n");
AppendMenu(hFileMenu, MF_STRING, MENU::OPEN, "Open \t ctrl+o");
AppendMenu(hFileMenu, MF_STRING, MENU::SAVE, "Save \t ctrl+s");
AppendMenu(hFileMenu, MF_STRING, MENU::SAVEAS, "Save As...");
AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);//просто лини¤
AppendMenu(hFileMenu, MF_STRING, MENU::EXIT, "Exit \t alt+f4");
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, "File");
//EDIT
HMENU hEditMenu = CreateMenu();
AppendMenu(hEditMenu, MF_STRING, MENU::UNDO, "Undo");
AppendMenu(hEditMenu, MF_STRING, 2, "Redo");
AppendMenu(hEditMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hEditMenu, MF_STRING, 2, "Copy");
AppendMenu(hEditMenu, MF_STRING, 2, "Past");
AppendMenu(hEditMenu, MF_SEPARATOR, NULL, NULL);
//submenu
HMENU hEditSubMenu = CreateMenu();
AppendMenu(hEditSubMenu, MF_STRING, 12, "SubMenu Item1");
AppendMenu(hEditSubMenu, MF_STRING, 12, "SubMenu Item2");
AppendMenu(hEditSubMenu, MF_STRING, 12, "SubMenu Item3");
AppendMenu(hEditMenu, MF_POPUP, (UINT_PTR)hEditSubMenu, "Open SubMenu");

AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hEditMenu, "Edit");

//INFO
AppendMenu(hMenu, MF_STRING, NULL, "Info");

SetMenu(hWnd, hMenu);
};

WndProc.h
Код:
#ifndef WNDPROC_H
#define WNDPROC_H

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

#endif WNDPROC_H

WndProc.cpp
Код:
#include <windows.h>
#include "TopMenu.h"

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
HDC hDC;
PAINTSTRUCT ps;
RECT rect;

switch (uMsg)
{
case WM_CREATE:
AddMenu(hWnd);
break;

case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, "HELLO WORLD", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;

case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

return 0;
};

командная строка
Код:
g++ main.cpp TopMenu.cpp WndProc.cpp -mwindows
давно
Старший Модератор
17042
808
24.06.2019, 13:29
общий
Консультация закрыта, т.к. автор сам ответил на свой вопрос.
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
Форма ответа