С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.98/47: Рейтинг темы: голосов - 47, средняя оценка - 4.98
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101

Отслеживание подключения по usb порту

01.05.2017, 11:46. Показов 10492. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите пример кода как отслеживать подключение по usb порту.
И дайте по возможности где об этом почитать можно.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.05.2017, 11:46
Ответы с готовыми решениями:

подключения к USB порту телефона Нокиа не удается
Всем привет! Вот такая проблемка: После установки ПО для тел. NOKIA подключаю его к USB. В трее появляется надпись "найдено новое...

Отслеживание подключения флешки по USB
Такой вопрос: чем увидеть подключаемую к компу флешку USB, где в реестре об этом хранится информация и как програмно запустить с этой...

Отслеживание подключения USB-token
Здравствуйте, никак не могу разобраться с usb listener, облазил все, понимаю что есть javax, usb4java и тд, но ни как подключить ни как...

17
58 / 14 / 5
Регистрация: 07.04.2017
Сообщений: 58
01.05.2017, 19:33
Deczy, Registering for Device Notification
1
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
03.05.2017, 07:23
эти функции могут помочь:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
///////////////////////////////
// ПОЛУЧЕНИЕ СПИСКА УСТРОЙСТВ
///////////////////////////////
 
// Получение списка классов
CMAPI CONFIGRET WINAPI CM_Enumerate_Classes(    // получение списка классов. вызывается в цикле начиная с индекса 0. 
                                                // если функция вернула CR_NO_SUCH_VALUE, значит пришли к концу списка
            IN ULONG ulClassIndex,              // индекс класса
            OUT LPGUID ClassGuid,               // указатель GUID класса
            IN ULONG ulFlags                    // не используется
);
 
// Получение информации о классе
WINSETUPAPI BOOL WINAPI SetupDiGetClassDescription(
            IN LPGUID ClassGuid,                //указатель на GUID класса
            OUT PTSTR ClassDescription,         //указатель на буфер, в который будет сохранена строка с именем класса
            IN DWORD ClassDescriptionSize,      //размер буфера
            OUT PDWORD RequiredSize OPTIONAL    //если размера буфера не хватит, то в этот параметр вернется указатель 
                                                //на переменную с требуемым размером буфера
);
 
// Получение хендла списка устройств, принадлежащих некоторому классу
HDEVINFO SetupDiGetClassDevs(
            IN LPGUID ClassGuid, OPTIONAL       // класс устройств для перечисления
                                                // если параметр равен 0, то перечислятся будут все классы в системе
            IN PCTSTR Enumerator, OPTIONAL      // имя PNP перечислителя, может быть равен 0
            IN HWND hwndParent, OPTIONAL        // хендл формы, может быть равен 0
            IN DWORD Flags                      // может принимать значение или их комбинацию
                                                //   DIGCF_ALLCLASSES - будет возвращен список всех устройств и всех классов
                                                //   DIGCF_DEVICEINTERFACE - возврат списка устройств, которые поддерживают интерфейсы
                                                //   DIGCF_DEFAULT - Возврат списка устройств, которые ассоциируются с системой по умолчанию
                                                //   DIGCF_PRESENT - Возврат списка устройств, которые в настоящее время присутствуют в системе
                                                //   DIGCF_PROFILE - Возврат списка устройств, которые являются частью текущего аппаратного профиля
);
 
// Перечисление списка устройств
WINSETUPAPI BOOL WINAPI SetupDiEnumDeviceInfo(  // пречисление производится в цикле, начиная от 0, и пока не получим отрицательный результат
                                                // если фунция вернла TRUE, то информация извлечена успешно
                                                // если FALSE, то обычно это означает, что пришли к концу списка 
            IN HDEVINFO DeviceInfoSet,          // хендл списка устройств
            IN DWORD MemberIndex,               // индекс в списке
            OUT PSP_DEVINFO_DATA DeviceInfoData // указатель на структуру, в которой будет сохранена информация об устройстве
 );
 
// перечисление интерфейсов устройства
BOOL SetupDiEnumDeviceInterfaces(               // у устройства может не быть интерфейса
            IN HDEVINFO DeviceInfoSet,                          // хендл списка устройств
            IN PSP_DEVINFO_DATA, OPTIONAL DeviceInfoData,       // указатель на структуру с информацией об устройстве
            IN const GUID *InterfaceClassGuid,                  // указатель на GUID класса
            IN DWORD MemberIndex,                               // индекс в списке
            OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData   // указатель на структуру, в которой будет сохранена информация об интерфейсе устройства
);
 
typedef struct _SP_DEVINFO_DATA {               // структура, в которой хранится информация об устройстве
            DWORD cbSize;                       // резмер структуры SP_DEVINFO_DATA в байтах
            GUID ClassGuid;                     // GUID класса
            DWORD DevInst;                      // хендл устройства
            ULONG_PTR Reserved;                 // Резерв. для внутреннего использования
} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;
 
// Получить имя устройства (или его описание)
WINSETUPAPI BOOL WINAPI SetupDiGetDeviceRegistryProperty(
            IN HDEVINFO DeviceInfoSet,                  // хендл списка устройств
            IN PSP_DEVINFO_DATA DeviceInfoData,         // указатель на структуру с информацией об устройстве
            IN DWORD Property,                          // тип информации, которую мы хотим получить
                                                        //   SPDRP_FRIENDLYNAME и SPDRP_DEVICEDESC - иногда информация может быть представлена для одного из парметров
            OUT PDWORD PropertyRegDataType, OPTIONAL    // указатель на переменную для типа данных ключа реестра из которого извлечена информация
            OUT PBYTE PropertyBuffer,                   // указатель на буфер для сохранения информации
            IN DWORD PropertyBufferSize,                // размер буфера
            OUT PDWORD RequiredSize OPTIONAL            // размер реально скопированных данных
);
 
//////////////////////////////////////
// ВКЛЮЧЕНИЕ И ОТКЛЮЧЕНИЕ УСТРОЙСТВ
//////////////////////////////////////
 
// Управляет состоянием устройства
// все параметры нуждаются в утверждении, поэтому функцию нужно вызывать 2 раза
// если  после первого вызова функция возвратила истинное значение, значит можно вызывать функцию второй раз
WINSETUPAPI BOOL WINAPI SetupDiSetClassInstallParams(       // с помощью этой функции можно производить различные действия с устройствами
                                                            // но, для каждого действия используются различные структуры
            IN HDEVINFO DeviceInfoSet,                      // хендл списка устройств
            IN PSP_DEVINFO_DATA DeviceInfoData              // указатель на структуру с информацией об устройстве
            IN PSP_CLASSINSTALL_HEADER ClassInstallParams   // указатель на структуру _SP_PROPCHANGE_PARAMS
            IN DWORD ClassInstallParamsSize                 // рпзмер структуры _SP_PROPCHANGE_PARAMS
);
 
// структура передаваемая в функцию
typedef struct _SP_PROPCHANGE_PARAMS {
            SP_CLASSINSTALL_HEADER ClassInstallHeader;  // структура определяющая производимую операцию
            DWORD StateChange;                          //   DICS_ENABLE - устройство будет включено
                                                        //   DICS_DISABLE - устройство будет выключено
                                                        // данный параметр определяется перед вторым вызовом функции
            DWORD Scope;                                //   DICS_FLAG_GLOBAL - изменения вступят в силу для всех аппаратных профилей
                                                        //   DICS_FLAG_CONFIGSPECIFIC - изменения вступят в силу только для указанного аппаратного профиля
                                                        // данный параметр определяется перед вторым вызовом функции
            DWORD HwProfile;                            // ID аппаратного профиля, к которому будут применяться изменения
                                                        // если он равен 0, то текущий аппаратный профиль
} SP_PROPCHANGE_PARAMS, *PSP_PROPCHANGE_PARAMS;
 
// структура определяющая производимую операцию
typedef struct _SP_CLASSINSTALL_HEADER {
            DWORD cbSize;                               // передаем размер структуры _SP_CLASSINSTALL_HEADER
            DI_FUNCTION InstallFunction;                // производимая над устройством операция
                                                        //   DIF_PROPERTYCHANGE - для включения/отключения устройства
                                                        // данный параметр определяется перед вторым вызовом функции
} SP_CLASSINSTALL_HEADER, *PSP_CLASSINSTALL_HEADER;
 
// вызвать устанофщик класса, для того чтобы изменения вступили в силу после изменения состояния устройства
WINSETUPAPI BOOL WINAPI SetupDiCallClassInstaller(
            IN DI_FUNCTION InstallFunction,             // код произведенной операции
                                                        //   DIF_PROPERTYCHANGE - для включения/отключения устройства
            IN HDEVINFO DeviceInfoSet,                  // хендл списка устройств
            IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL // указатель на структуру с информацией об устройстве
);
 
//////////////////////////////////////
// БЕЗОПАСНОЕ ИЗВЛЕЧЕНИЕ УСТРОЙСТВА
//////////////////////////////////////
 
// функция безопасного извлечения устройства
CMAPI CONFIGRET WINAPI CM_Request_Device_Eject(
            IN DEVINST dnDevInst,               // хендл устройства
            OUT PPNP_VETO_TYPE pVetoType,       // указатель на переменную, в который будет сохранен код причины при неудаче
                                                // опционально, может быть равен 0
            OUT LPTSTR pszVetoName,             // указатель на строку в которую будет сохранена причина неудачи
                                                // опционально, может быть равен 0
                                                // если равен 0, то сообщение выведет система
            IN ULONG ulNameLength,              // максимальная длина строки
            IN ULONG ulFlags                    // не используется
);
 
// функция получает указатель на родитель устройства
CMAPI CONFIGRET WINAPI CM_Get_Parent(
            OUT PDEVINST pdnDevInst,            // указатель на хендл родителя устройства
            IN  DEVINST dnDevInst,              // хендл устройства
            IN  ULONG ulFlags                   // не используется
);
 
// выдает размер строки ID устройства
CMAPI CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(
            OUT PULONG pulLen,                  // указатель на переменную для записи длины строки
            IN DEVINST dnDevInst,               // хендл устройства
            IN ULONG ulFlags,                   // не используется
            IN HMACHINE hMachine, OPTIONAL
);
 
// выдает размер строки ID устройства
CMAPI CONFIGRET WINAPI CM_Get_Device_ID_Size(
            OUT PULONG pulLen,                  // указатель на переменную для записи длины строки
            IN DEVINST dnDevInst,               // хендл устройства
            IN ULONG ulFlags,                   // не используется
);
 
// функция возвращает ID устройства
CMAPI CONFIGRET WINAPI CM_Get_Device_ID(
            IN DEVINST dnDevInst,               // хендл устройства
            OUT PWSTR Buffer,                   // указатель на буфер для записи строки идентификатора
            IN ULONG BufferLen,                 // длина строки идентификатора в символах
            IN ULONG ulFlags                    // не используется
);
1
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
03.05.2017, 07:29
работа с функциями на примере безопасного отключения всех USB-накопителей
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <windows.h>
#include <Cfgmgr32.h>
#include <SetupAPI.h>
#include <stdio.h>
#include "resource.h"       // для корректной работы выполнить запуск от имени администратора (например через манифест)
 
BOOL GetGUIDfromStr(char str[39], GUID *guid);
BOOL GetStrfromGUID(GUID *guid, char str[39]);
BOOL IsUSBDevice(DWORD DevInst);
BOOL RemoveUSBDevices();
 
int main()
{
    RemoveUSBDevices();
    
    return 0;
}
 
BOOL GetGUIDfromStr(char str[39], GUID *guid)   // получаем структуру GUID по его строковому описанию
{
    // первый параметр - строка вида char str[] = "{22345200-abe8-4f60-90c8-0d43c5f6c0f6}"
    // в случае ошибки функция возвращает FALSE и обнуляет значение в guid
    // в противном случае возвращает TRUE
    bool error_flag = false;
    int i1, i2;
    
    for(int i =0; i<38; i++)
    {
        if ((i == 0) || (i == 9) || (i == 14) || (i == 19) || (i == 24) || (i == 37))
        {
            switch(str[i])
            {
                case '{': case '-': case '}': continue; break;
                default: error_flag = true; break;
            }
        }
        else
        {
            i1 = i2 = 0;
            switch(str[i])
            {
                case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
                    i1 = (int)((BYTE)(str[i]) - 48) * 16;
                break;
                case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                    i1 = (int)((BYTE)(str[i]) - 87) * 16;
                break;
                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                    i1 = (int)((BYTE)(str[i]) - 55) * 16;
                break;
                default:
                    error_flag = true;
                break;
            }
            switch(str[i+1])
            {
                case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
                    i2 = (int)((BYTE)(str[i+1]) - 48);
                break;
                case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                    i2 = (int)((BYTE)(str[i+1]) - 87);
                break;
                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                    i2 = (int)((BYTE)(str[i+1]) - 55);
                break;
                default:
                    error_flag = true;
                break;
            }
        }
        if (error_flag == true)
        {
            guid->Data1 = 0;
            guid->Data2 = 0;
            guid->Data3 = 0;
            for(int j=0; j<8; j++) guid->Data4[j] = 0;
            return FALSE;
        }
        else
        {
            switch(i)
            {
                case 1: ((BYTE*)guid)[3] = i1+i2; break;
                case 3: ((BYTE*)guid)[2] = i1+i2; break;
                case 5: ((BYTE*)guid)[1] = i1+i2; break;
                case 7: ((BYTE*)guid)[0] = i1+i2; break;
                case 10: ((BYTE*)guid)[5] = i1+i2; break;
                case 12: ((BYTE*)guid)[4] = i1+i2; break;
                case 15: ((BYTE*)guid)[7] = i1+i2; break;
                case 17: ((BYTE*)guid)[6] = i1+i2; break;
                case 20: ((BYTE*)guid)[8] = i1+i2; break;
                case 22: ((BYTE*)guid)[9] = i1+i2; break;
                case 25: ((BYTE*)guid)[10] = i1+i2; break;
                case 27: ((BYTE*)guid)[11] = i1+i2; break;
                case 29: ((BYTE*)guid)[12] = i1+i2; break;
                case 31: ((BYTE*)guid)[13] = i1+i2; break;
                case 33: ((BYTE*)guid)[14] = i1+i2; break;
                case 35: ((BYTE*)guid)[15] = i1+i2; break;
            }
            i++;
        }
    }
    return TRUE;
}
 
BOOL GetStrfromGUID(GUID *guid, char str[39])   // получаем строковое описание GUID по его структуре
{
    memset(str, 0, 39);
    str[0] = '{';
    if (((BYTE*)guid)[3] < 16) {str[1] = '0'; sprintf(&(str[2]), "%x", (int)((BYTE*)guid)[3]);}
    else sprintf(&(str[1]), "%x", (int)((BYTE*)guid)[3]);
    if (((BYTE*)guid)[2] < 16) {str[3] = '0'; sprintf(&(str[4]), "%x", (int)((BYTE*)guid)[2]);}
    else sprintf(&(str[3]), "%x", (int)((BYTE*)guid)[2]);
    if (((BYTE*)guid)[1] < 16) {str[5] = '0'; sprintf(&(str[6]), "%x", (int)((BYTE*)guid)[1]);}
    else sprintf(&(str[5]), "%x", (int)((BYTE*)guid)[1]);
    if (((BYTE*)guid)[0] < 16) {str[7] = '0'; sprintf(&(str[8]), "%x", (int)((BYTE*)guid)[0]);}
    else sprintf(&(str[7]), "%x", (int)((BYTE*)guid)[0]);
    str[9] = '-';
    if (((BYTE*)guid)[5] < 16) {str[10] = '0'; sprintf(&(str[11]), "%x", (int)((BYTE*)guid)[5]);}
    else sprintf(&(str[10]), "%x", (int)((BYTE*)guid)[5]);
    if (((BYTE*)guid)[4] < 16) {str[12] = '0'; sprintf(&(str[13]), "%x", (int)((BYTE*)guid)[4]);}
    else sprintf(&(str[12]), "%x", (int)((BYTE*)guid)[4]);
    str[14] = '-';
    if (((BYTE*)guid)[7] < 16) {str[15] = '0'; sprintf(&(str[16]), "%x", (int)((BYTE*)guid)[7]);}
    else sprintf(&(str[15]), "%x", (int)((BYTE*)guid)[7]);
    if (((BYTE*)guid)[6] < 16) {str[17] = '0'; sprintf(&(str[18]), "%x", (int)((BYTE*)guid)[6]);}
    else sprintf(&(str[17]), "%x", (int)((BYTE*)guid)[6]);
    str[19] = '-';
    if (((BYTE*)guid)[8] < 16) {str[20] = '0'; sprintf(&(str[21]), "%x", (int)((BYTE*)guid)[8]);}
    else sprintf(&(str[20]), "%x", (int)((BYTE*)guid)[8]);
    if (((BYTE*)guid)[9] < 16) {str[22] = '0'; sprintf(&(str[23]), "%x", (int)((BYTE*)guid)[9]);}
    else sprintf(&(str[22]), "%x", (int)((BYTE*)guid)[9]);
    str[24] = '-';
    if (((BYTE*)guid)[10] < 16) {str[25] = '0'; sprintf(&(str[26]), "%x", (int)((BYTE*)guid)[10]);}
    else sprintf(&(str[25]), "%x", (int)((BYTE*)guid)[10]);
    if (((BYTE*)guid)[11] < 16) {str[27] = '0'; sprintf(&(str[28]), "%x", (int)((BYTE*)guid)[11]);}
    else sprintf(&(str[27]), "%x", (int)((BYTE*)guid)[11]);
    if (((BYTE*)guid)[12] < 16) {str[29] = '0'; sprintf(&(str[30]), "%x", (int)((BYTE*)guid)[12]);}
    else sprintf(&(str[29]), "%x", (int)((BYTE*)guid)[12]);
    if (((BYTE*)guid)[13] < 16) {str[31] = '0'; sprintf(&(str[32]), "%x", (int)((BYTE*)guid)[13]);}
    else sprintf(&(str[31]), "%x", (int)((BYTE*)guid)[13]);
    if (((BYTE*)guid)[14] < 16) {str[33] = '0'; sprintf(&(str[34]), "%x", (int)((BYTE*)guid)[14]);}
    else sprintf(&(str[33]), "%x", (int)((BYTE*)guid)[14]);
    if (((BYTE*)guid)[15] < 16) {str[35] = '0'; sprintf(&(str[36]), "%x", (int)((BYTE*)guid)[15]);}
    else sprintf(&(str[35]), "%x", (int)((BYTE*)guid)[15]);
    str[37] = '}';
    return TRUE;
}
 
BOOL IsUSBDevice(DWORD DevInst)
{
    DWORD size;
    LPBYTE pData;
    BOOL usb = FALSE;
    if (CM_Get_Device_ID_Size(&size, DevInst, 0) == CR_SUCCESS)         // получаем размер строки ID устройства
    {
        if (size)
        {
            pData = (LPBYTE)GlobalAlloc(GPTR, size + 1);                // выделяем глобальный блок памяти фиксированного размера и инициализированный нулями
            if (pData)                                                  // если дескриптор блока памяти был получен
            {
                if (CM_Get_Device_ID(DevInst, (PCHAR)pData, size + 1,0) == CR_SUCCESS)  // получаем ID устройства в pData
                {
                    *(pData + 7) = 0x00;                                // зануляем босьмой байт строки (т.е. получаем строку из семи символов)
                    if (!strcmp((char*)pData, "USBSTOR")) usb = TRUE;   // сравиваем строки 
                }
                GlobalFree(pData);                                      // освобождаем память
            }
        }
    }
    return usb;
}
 
BOOL RemoveUSBDevices()
{
    // если все устройства выгружены, то функция возвращает TRUE
    // если хотябы одно устройство осталось не выгружено, тогда FALSE
    GUID GUID_DEVCLASS_DISKDRIVE; // хранилище для GUID'а класса устройств
    GetGUIDfromStr("{4D36E967-E325-11CE-BFC1-08002BE10318}\0", &GUID_DEVCLASS_DISKDRIVE);       // преобразуем к структуре GUID константу, соответствующую USB-дисковым устройствам
    
    HDEVINFO DrivesPnPHandle;     // список устройств
    DrivesPnPHandle = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT); // возвращает указатель на список описателей устройств находящихся в системе
    if(DrivesPnPHandle == INVALID_HANDLE_VALUE) return FALSE;
    
    SP_DEVINFO_DATA DevInfo;                                        // структура определяющая устройство
    DevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
    
    BOOL remove_all_USB = TRUE;
    DWORD index = 0;                                                // счетчик устройств
    DWORD Parent;
    while(SetupDiEnumDeviceInfo(DrivesPnPHandle, index, &DevInfo))  //функция перечисляет устройства и записывает структуру очередного устройства в DevInfo
    {
        if (IsUSBDevice(DevInfo.DevInst) && (CM_Get_Parent(&Parent, DevInfo.DevInst, 0) == CR_SUCCESS)) // если устройство является usb-накопителем и у него есть родитель
        {
            char str[1024];
            memset(str, 0, 1024);
            CM_Request_Device_Eject(Parent, NULL, str, 1024, 0);        // осуществляем безопасное извлечение устройства
            if (str[0] != 0) remove_all_USB = FALSE;
        }
        index++;
    }
    SetupDiDestroyDeviceInfoList(DrivesPnPHandle);                  // освобождаем список устройств
    return remove_all_USB;
}
1
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
06.05.2017, 00:20
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <cstdio>
#include <windows.h>
 
int main (int argc, char *argv [])
{
    DWORD dwSize1 = GetLogicalDriveStrings (0, NULL);
    int state = 0;
    while (1)
    {
         DWORD dwSize2 = GetLogicalDriveStrings (0, NULL);
         if (dwSize2 != dwSize1)
              state = 1;
         if (state == 1)
         {
              if (dwSize2 > dwSize1)
                   printf ("USB devices added!\n");
              else if ( dwSize2 < dwSize1)
                   printf ("USB devices removed!\n");
              dwSize1 = dwSize2;
              state = 0;
         }
         Sleep (500);
    }
    return 0;
}
2
Эксперт .NET
 Аватар для Rius
13069 / 7630 / 1669
Регистрация: 25.05.2015
Сообщений: 23,199
Записей в блоге: 14
06.05.2017, 07:50
decrement, а если программа должна делать ещё что-то полезное? А если реагировать на подключение нужно мгновенно, а не раз в полсекунды? А если подключение диска не добавляет букву диска? А если подключённый диск с буквой не является USB-шным, а нужны именно USB?
Решения показаны выше.
2
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101
09.05.2017, 01:12  [ТС]
а как отследить вообще любое устройство и узнать его vid/pid?
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
09.05.2017, 10:10
цитата из хакера: "Достаточно написать код, обрабатывающий событие WM_DEVICECHANGE"
Фишка №1: в любом месте веселее вместе
Мониторим флешки
0
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101
10.05.2017, 16:46  [ТС]
Я прочитал про windproc, то есть это некая функция которая обрабатывает сообщения виндовс, про все ее параметры и хендлы я тоже знаю, но не понял как ей пользоваться. Она идет вместо основной функции main или отдельно?
Попробовал написать программу которая при отключении любого usb девайса выводит "yes"

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<Windows.h>
#include<iostream>
 
LRESULT CALLBACK WindowProc(    HWND hwnd,
                                UINT message,
                                WPARAM wParam,
                                LPARAM lParam   ) {
    while (1)
    {
        if (message == WM_DEVICECHANGE)
        {
            std::cout << "yes!";
        }
        Sleep(5000);
    }
}
0
Эксперт .NET
 Аватар для Rius
13069 / 7630 / 1669
Регистрация: 25.05.2015
Сообщений: 23,199
Записей в блоге: 14
10.05.2017, 16:49
Грабли с WM_DEVICECHANGE
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
11.05.2017, 08:04
Лучший ответ Сообщение было отмечено Deczy как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DEVICECHANGE:
                std::cout << "yes!";
        break;
        case WM_DESTROY: PostQuitMessage(0); break;
        default: return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}
не должно быть никаких Sleep(), т.е. оно тут ни к чему
WM_DEVICECHANGE - это широковещательное сообщение происходящее при изменении состояния устройств
Ваше приложение (и не только Ваше) его получит в реальном времени (как только)

Минимальный шаблон оконного приложения:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <windows.h>
 
HWND hwndg;
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    WNDCLASSEX w;
    memset(&w,0,sizeof(w));
    w.cbSize = sizeof(WNDCLASSEX);
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.lpfnWndProc = WndProc;
    w.hInstance = hInstance;
    w.hCursor = LoadCursor(NULL, IDC_ARROW);
    w.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    w.lpszClassName = "GUIClass";
    
    if (RegisterClassEx(&w) == 0)
    {
        exit(1);
    }
 
    hwndg = CreateWindowEx(0, "GUIClass", "GUI_Title", WS_BORDER | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, 10, 10, 215, 150, NULL, NULL, hInstance, NULL);
    
    ShowWindow(hwndg, nCmdShow);
    UpdateWindow(hwndg);
 
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch(Message)
    {
        case WM_DESTROY: PostQuitMessage(0); break;
        default: return DefWindowProc(hwnd, Message, wparam, lparam);
    }
    return 0;
}

WinMain - замена main
WndProc - обработчик приходящих окну сообщений. Как только окно получило сообщение, оно пропускается через обработчик
2
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101
12.05.2017, 14:57  [ТС]
И наверно последний вопрос как мне таким образом получать сообщения через свою форму заменить "WNDCLASSEX" на свой класс формы?
0
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101
14.05.2017, 02:42  [ТС]
как мне таким образом получать сообщения через свою форму заменить "WNDCLASSEX" на свой класс формы?
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
14.05.2017, 15:56
если у Вас есть форма то используйте свой класс, если консольное приложение то можете использовать аргументы функции main для этих целей, либо создать новый класс и им обрабатывать сообщения.
1
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101
18.05.2017, 02:29  [ТС]
Я в проект добавил хедер с формой по шаблону windows forms, потом в функции регистрации окна заменяю WNDCLASSEXW на свой класс окна, я правильно понял?
И еще он не идентифицирует пространство имен System, проект был создан как win32/приложения Windows, я так понял мне просто нужно пересоздать проект как WindowsForms и перенести все необходимое или как?
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
18.05.2017, 05:52
Выкладывайте Ваш код с комментариями, и в них напишите что от программы требуется. а также для чего пространство имен System планируете использовать.
0
0 / 0 / 0
Регистрация: 16.02.2016
Сообщений: 101
22.05.2017, 11:45  [ТС]
Да кода толком и нет потому что нужен интерфейс, нужно окно как windows forms и что бы когда приходило сообщение WM_DEVICECHANGE выводилась строка тип устройство подключено.
То есть как я делал, я создаю в визуал студии проект Win32/приложение Windows сразу же в шаблоне этого проекта готовая оконная процедура и прочее а как написать интерфейс я не знаю. Я знаю windows forms добавляю в раздел хедер, класс Windows Forms (MyForm.h) но во первых так как это разные проекты так делать нельзя и из комментариев на других форумах я прочитал что для написания окна для проекта Win32 нужно что-то добавлять в ресурсы, а что добавлять как не ясно. Может вы хоть как-то просветите меня...Мне сдавать скоро, а я ничего не понимаю(Взываю о помощи!!!)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "stdafx.h"
#include "Win32Project2.h"
 
#define MAX_LOADSTRING 100
 
// Глобальные переменные:
HINSTANCE hInst;                                // текущий экземпляр
WCHAR szTitle[MAX_LOADSTRING];                  // Текст строки заголовка
WCHAR szWindowClass[MAX_LOADSTRING];            // имя класса главного окна
 
// Отправить объявления функций, включенных в этот модуль кода:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
 
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    // TODO: разместите код здесь.
 
    // Инициализация глобальных строк
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WIN32PROJECT2, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
 
    // Выполнить инициализацию приложения:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }
 
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT2));
 
    MSG msg;
 
    // Цикл основного сообщения:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}
 
 
 
//
//  ФУНКЦИЯ: MyRegisterClass()
//
//  НАЗНАЧЕНИЕ: регистрирует класс окна.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW 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          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT2));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WIN32PROJECT2);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    return RegisterClassExW(&wcex);
}
 
//
//   ФУНКЦИЯ: InitInstance(HINSTANCE, int)
//
//   НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
//
//   КОММЕНТАРИИ:
//
//        В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
//        создается и выводится на экран главное окно программы.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
 
   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
 
   if (!hWnd)
   {
      return FALSE;
   }
 
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
 
   return TRUE;
}
 
//
//  ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  НАЗНАЧЕНИЕ:  обрабатывает сообщения в главном окне.
//
//  WM_COMMAND — обработать меню приложения
//  WM_PAINT — отрисовать главное окно
//  WM_DESTROY — отправить сообщение о выходе и вернуться
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Разобрать выбор в меню:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Добавьте сюда любой код прорисовки, использующий HDC...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
// Обработчик сообщений для окна "О программе".
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;
 
    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
Добавлено через 15 секунд
Да кода толком и нет потому что нужен интерфейс, нужно окно как windows forms и что бы когда приходило сообщение WM_DEVICECHANGE выводилась строка тип устройство подключено.
То есть как я делал, я создаю в визуал студии проект Win32/приложение Windows сразу же в шаблоне этого проекта готовая оконная процедура и прочее а как написать интерфейс я не знаю. Я знаю windows forms добавляю в раздел хедер, класс Windows Forms (MyForm.h) но во первых так как это разные проекты так делать нельзя и из комментариев на других форумах я прочитал что для написания окна для проекта Win32 нужно что-то добавлять в ресурсы, а что добавлять как не ясно. Может вы хоть как-то просветите меня...Мне сдавать скоро, а я ничего не понимаю(Взываю о помощи!!!)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "stdafx.h"
#include "Win32Project2.h"
 
#define MAX_LOADSTRING 100
 
// Глобальные переменные:
HINSTANCE hInst;                                // текущий экземпляр
WCHAR szTitle[MAX_LOADSTRING];                  // Текст строки заголовка
WCHAR szWindowClass[MAX_LOADSTRING];            // имя класса главного окна
 
// Отправить объявления функций, включенных в этот модуль кода:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
 
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    // TODO: разместите код здесь.
 
    // Инициализация глобальных строк
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WIN32PROJECT2, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
 
    // Выполнить инициализацию приложения:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }
 
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT2));
 
    MSG msg;
 
    // Цикл основного сообщения:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}
 
 
 
//
//  ФУНКЦИЯ: MyRegisterClass()
//
//  НАЗНАЧЕНИЕ: регистрирует класс окна.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW 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          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT2));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WIN32PROJECT2);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    return RegisterClassExW(&wcex);
}
 
//
//   ФУНКЦИЯ: InitInstance(HINSTANCE, int)
//
//   НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
//
//   КОММЕНТАРИИ:
//
//        В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
//        создается и выводится на экран главное окно программы.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
 
   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
 
   if (!hWnd)
   {
      return FALSE;
   }
 
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
 
   return TRUE;
}
 
//
//  ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  НАЗНАЧЕНИЕ:  обрабатывает сообщения в главном окне.
//
//  WM_COMMAND — обработать меню приложения
//  WM_PAINT — отрисовать главное окно
//  WM_DESTROY — отправить сообщение о выходе и вернуться
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Разобрать выбор в меню:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Добавьте сюда любой код прорисовки, использующий HDC...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
// Обработчик сообщений для окна "О программе".
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;
 
    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
23.05.2017, 10:26
Цитата Сообщение от Deczy Посмотреть сообщение
Может вы хоть как-то просветите меня...
Хоть это немного не по теме, но..

Интерфейс и архитектура win32-проекта на пальцах (начало было в предыдущих постах), продолжение.

работа с ресурсами (на примере добавления курсора и иконок):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
////////////////////////////////
// файл main.cpp
////////////////////////////////
#include <windows.h>
#include "resource.h"  
 
HICON hIcon, hIconSm;
HCURSOR htSight, hcArrow;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    WNDCLASSEX w;
    
    // . . .
    hcArrow = LoadCursor(NULL, IDC_ARROW);    // стандартный курсор "стрелка"
    htSight = LoadCursor(hInstance, MAKEINTRESOURCE(CURSOR_RED)); // не стандартный, анимированный курсор
    hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(MAIN_ICON));
    hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(MAIN_ICONSM));
    w.hCursor = hcArrow;
    w.hIcon = hIcon;
    w.hIconSm = hIconSm;
    
    // . . .
}
C++
1
2
3
4
5
6
////////////////////////////////
// файл resource.h
////////////////////////////////
#define MAIN_ICON 1691
#define MAIN_ICONSM 1692
#define CURSOR_RED 1693
C++
1
2
3
4
5
6
7
8
////////////////////////////////
// файл resource.rc
////////////////////////////////
#include "resource.h"
#define ANICURSOR 21  // включаем в проект тип "анимированный курсор"
MAIN_ICON ICON "icon.ico"  // иконка файла
MAIN_ICONSM ICON "icon.ico" // иконка в области заголовка окна
CURSOR_RED ANICURSOR "cursor_red.ani" // используем тип "анимированный курсор" и подключаем соответствующий файл
// в папке с проектом должны лежать соответствующие файлы, иначе проект не скомпилируется[/CPP]

// если на первом этапе не планируете украшательств, закомментируйте все связанные с ресурсами строки в своем проекте

работа с ресурсами (панель меню):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
///////////////////////////////////////////////////
// Файл recource.h
///////////////////////////////////////////////////
#define MAIN_MENU 1700
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
///////////////////////////////////////////////////
// Файл recource.rc
///////////////////////////////////////////////////
#include "resource.h"
 
MAIN_MENU MENU
{
    POPUP "&File"
    {
        MENUITEM "&Open...\tCtrl-O", 2
        MENUITEM "&Save", 3
        MENUITEM "Save &As...", 4
        MENUITEM SEPARATOR
        MENUITEM "&Hex view", 5, CHECKED GRAYED     // пункт меню с галочкой (CHECKED) и заблокирован (GRAYED)
        MENUITEM "&Exit\tAlt-F4", 6
    }
    POPUP "&Edit"
    {
        MENUITEM "&Copy", 7
        MENUITEM "&Paste", 8
        POPUP "Popup"
        {
            MENUITEM "1", 9
            MENUITEM "2", 10
            MENUITEM "3", 11
        }
        MENUITEM SEPARATOR
        MENUITEM "Search", 12
    }
    POPUP "&Help"
    {
        MENUITEM "&About...\tF1", 13
    }
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
///////////////////////////////////////////////////
// Файл main.cpp
///////////////////////////////////////////////////
#include <windows.h>
#include "resource.h"
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    WNDCLASSEX w;
    // ...
    w.lpszMenuName = MAKEINTRESOURCE(MAIN_MENU);
    // ...
    return 0;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch(Message)
    {
        case WM_COMMAND:
            if (HIWORD(wparam)==0) 
            {
                char buf[256];
                switch (LOWORD(wparam)) 
                {
                    case 6:  /* команда меню Exit */
                        PostQuitMessage(0);
                    default: /* все остальные команды */
                        wsprintf(buf,"Command code: %d",LOWORD(wparam));
                        MessageBox(hwnd,buf,"MessageBox",MB_OK|MB_ICONINFORMATION);
                }
            }
            return 0;
        case WM_CREATE:
            GetWindowRect(hwndg, &rect);
        break;
        case WM_DESTROY: PostQuitMessage(0); break;
        default: return DefWindowProc(hwnd, Message, wparam, lparam);
    }
    return 0;
}


работа с ресурсами (панель статуса):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
 
HWND hwndg, hStatusWindow;
// . . . 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // . . .
    LoadLibrary("comctl32.dll");
    // . . . 
    hwndg = CreateWindowEx(/* . . . */);
    hStatusWindow = CreateStatusWindowA(WS_CHILD | WS_VISIBLE, "Готово", hwndg, 4000);
    // . . . 
    return msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch(Message)
    {
        // . . . 
        case WM_SIZE:
        {
            // . . . 
            SendMessage(hStatusWindow, WM_SIZE, wparam, lparam);            
        }
        // . . . 
    }
    return 0;
}


для начала нужно попробовать создать приложение имеющее два окна с независимыми обработчиками сообщений:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <windows.h>
#include <stdio.h>
 
#define ID_BUTTON 10001
 
HWND hwndg, hsubwnd, hbtn;
 
// добавляем процедуру обработки сообщений окна для картинки
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK SubWndProc(HWND, UINT, WPARAM, LPARAM);
 
// немного измененная Ваша главная функция
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    
    WNDCLASSEX w;
    memset(&w,0,sizeof(w));
    w.cbSize = sizeof(WNDCLASSEX);
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.lpfnWndProc = WndProc;
    w.hInstance = hInstance;
    w.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    w.lpszClassName = "Window1";
    
    // дополнительный класс
    WNDCLASSEX subw;
    memset(&subw,0,sizeof(subw));
    subw.cbSize = sizeof(WNDCLASSEX);
    subw.style = CS_HREDRAW | CS_VREDRAW;
    subw.lpfnWndProc = SubWndProc;
    subw.hInstance = hInstance;
    subw.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    subw.lpszClassName = "Window2";
    
    if (RegisterClassEx(&w) == 0) exit(1);
    if (RegisterClassEx(&subw) == 0) exit(1);
    
    hwndg = CreateWindowEx(0, "Window1", "Окно 1", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, hInstance, NULL);
    hbtn = CreateWindowEx(0, "BUTTON", "Кнопка", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, 10, 10, 50, 25, hwndg, (HMENU)ID_BUTTON, hInstance, NULL);
    hsubwnd = CreateWindowEx(0, "Window2", "Окно 2", WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, hwndg, NULL, hInstance, NULL);
    // . . .
    
    ShowWindow(hwndg, nCmdShow);
    UpdateWindow(hwndg);
 
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch(Message)
    {
        case WM_COMMAND:
            switch (LOWORD(wparam)) 
            {
                case ID_BUTTON:
                    SetWindowPos(hsubwnd, HWND_NOTOPMOST, 200, 200, 100, 100, NULL);
                    EnableWindow(hwndg, FALSE);             // делаем главное окно неактивным
                    ShowWindow(hsubwnd, SW_SHOWNORMAL);     // отображаем дочернее окно
                    UpdateWindow(hsubwnd);
                break;
            }
        break;
        case WM_DESTROY: 
            PostQuitMessage(0); 
        break;
        default: return DefWindowProc(hwnd, Message, wparam, lparam);
    }
    return 0;
} 
 
LRESULT CALLBACK SubWndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch(Message)
    {
        case WM_CLOSE:  
            SetWindowPos(hsubwnd, HWND_NOTOPMOST,0, 0, 0, 0, NULL);                     // изменЯем до нулЯ размеры и позицию дочернего окна
            ShowWindow(hsubwnd,SW_HIDE);                                                // прЯчем дочернее окно
            EnableWindow(hwndg, TRUE);                                                  // разблокируем главное окно
            SetWindowPos(hwndg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);     // делаем главное окно верхним не изменЯЯ его размеров и позиции
        break;
        case WM_DESTROY: 
            PostQuitMessage(0); 
        break;
        default: return DefWindowProc(hwnd, Message, wparam, lparam);
    }
    return 0;
}


теперь ближе к вашему вопросу о ресурсах (о многофайловом пректе):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
///////////////////////////
// Файл global.h
///////////////////////////
 
HWND hwndg;
WNDCLASSEX w;
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
///////////////////////////
// Файл func.h
///////////////////////////
 
void SetClassParam(HINSTANCE hInst)
{
    memset(&w,0,sizeof(w));
    w.cbSize = sizeof(WNDCLASSEX);
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.lpfnWndProc = WndProc;
    w.hInstance = hInst;
    w.hCursor = LoadCursor(NULL, IDC_ARROW);
    w.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    w.lpszClassName = "GUIClass";
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
///////////////////////////
// Файл main.cpp
///////////////////////////
 
#include <windows.h>
 
#include "global.h"
#include "func.h"
 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    SetClassParam(hInstance);
    
    if (RegisterClassEx(&w) == 0)
    {
        exit(1);
    }
 
    hwndg = CreateWindowEx(0, "GUIClass", "GUI_Title", WS_BORDER | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, 10, 10, 215, 150, NULL, NULL, hInstance, NULL);
    
    ShowWindow(hwndg, nCmdShow);
    UpdateWindow(hwndg);
 
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
    switch(Message)
    {
        case WM_DESTROY: PostQuitMessage(0); break;
        default: return DefWindowProc(hwnd, Message, wparam, lparam);
    }
    return 0;
}

А вообще лучше не использовать тот шаблон, который Вам дает IDE. Создайте свой и в дальнейшем используйте в своих проектах
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.05.2017, 10:26
Помогаю со студенческими работами здесь

Отслеживание подключения USB устройств
Требуется написать консольное приложение (в дальнейшем службу) отслеживать любое подключение USB устройств и запись всей информации об...

Передать по воздуху от usb мыши к usb порту без провода
У меня есть мышь ss sensei wireless с убитой станцией приемника,аккумулятор мышь и выход usb у мыши целы,могу ли я с помощью...

Постоянная проверка подключения кабеля к com порту
Добрый день, как реализовать постоянную проверку подключения кабеля к com порту для данной функции? Т.е. если кабель выпадет, то нужно...

Отслеживание подключения к Wi-Fi
Добрый день, подскажите как можно отследить есть подключение к Wi-Fi или оно пропало?

Переодически перестают работать USB порты на материнке после подключения устройств к USB корпуса
Собственно проблема почти описана в заголовке. Довольно странная фигня. К материнке подключены клава и мышь. Происходит такое (не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru