Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
2 / 2 / 1
Регистрация: 18.03.2014
Сообщений: 147

Чат между окнами, обработка статуса WinApi

29.12.2014, 10:52. Показов 545. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почти доделал обработку статусов собеседника(онлайн, отошел) но столкнулся с проблемой, когда запускаешь 1 чат, в 3 текстовом поле пишется его статус, но в 1 чате это пишется, а во 2 пишется только название 1 чата, а статус нет, почему так, и еще как сделать пересылку статусов в 3 текстовом поле между 2 чатами, чтобы старое сообщение удалялось, а вместо него стояло новое( из контекстного меню)?
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#include "stdafx.h"
#include "lab6.h"
#include "windows.h"
#include <CommCtrl.h>
 
 
HINSTANCE hInst;
bool bSecondInstance;
HWND hWnd;
 
int APIENTRY WinMain(HINSTANCE hInstance, /* дескриптор текущего экземпляра приложения Дескриптор hInstance чаще всего требуется функциям, работающим с ресурсами программы.*/
    HINSTANCE hPrevInstance, /** дескриптор предыдущего экземпляра приложения , по умолчанию null */
    LPTSTR    lpCmdLine, /* указатель на начало командной строки, введенной при запуске программы. */
    int       nCmdShow) /* как окно должно быть показано  */
{
    MSG msg;//структура сообщения
    bSecondInstance = FindWindow(NULL, CAPTION_1/*"chat1"*/) != NULL;
    if (bSecondInstance && FindWindow(NULL, CAPTION_2/*"chat2"*/) != NULL)
    {
        MessageBox(NULL,  // дескриптор родительского окна
            "Два экземпляра программы уже запущены", // указатель на строку с сообщением
            "Ошибка", // указатель на строку с текстом заголовка              
            MB_ICONEXCLAMATION);// флаги для отображения кнопок, стиля пиктограммы и прочее
        return 1; //  код завершения программы
    }
 
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    MyRegisterClass(hInstance);
 
    if (!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }
    //создание статуса -  контекстное меню
    HWND hStatusWindow = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", hWnd, 5000);
    HMENU hMainMenu = CreateMenu();
    HMENU hPopMenuFile = CreatePopupMenu();
    HMENU hPopMenuStatus = CreatePopupMenu();
    AppendMenu(hMainMenu, MF_STRING | MF_POPUP, (UINT)hPopMenuFile, "Файл");
    {
        AppendMenu(hPopMenuFile, MF_STRING, IDB_SEND, "Отправить данные");
        AppendMenu(hPopMenuFile, MF_STRING, IDM_EXIT, "Выход");
    }
    AppendMenu(hMainMenu, MF_STRING | MF_POPUP, (UINT)hPopMenuStatus, "Статус");
    {
        AppendMenu(hPopMenuStatus, MF_STRING | MF_CHECKED | MF_UNCHECKED, IDB_ONLINE, "Онлайн");
        AppendMenu(hPopMenuStatus, MF_STRING | MF_CHECKED | MF_UNCHECKED, IDB_BUSY, "Занят");
        AppendMenu(hPopMenuStatus, MF_STRING | MF_CHECKED | MF_UNCHECKED, IDB_OUTOFPLACE, "Отошел");
        AppendMenu(hPopMenuStatus, MF_STRING | MF_CHECKED | MF_UNCHECKED, IDB_DONOTBOTHER, "Не беспокоить");
    }
 
    SetMenu(hWnd, hMainMenu);
    SetMenu(hWnd, hPopMenuFile);
    SetMenu(hWnd, hPopMenuStatus);
    //цикл сообщений приложения
    while (GetMessage(&msg, // указатель на структуру MSG
        NULL, // дескриптор окошка
        0,// фильтры
        0))// фильтры для выборки сообщений
    {
        if (!TranslateAccelerator(msg.hwnd, NULL, &msg))
        {
            TranslateMessage(&msg);  ///Эта функция переводит сообщения формата виртуальных клавиш в сообщения символы.
            DispatchMessage(&msg);   ///Функция DispatchMessage должна вызвать «функцию обработки сообщений».
        }
    }
    return (int)msg.wParam; //  код завершения программы
}
 
HWND GetOtherClientHandle()
{
    return FindWindow(NULL, bSecondInstance ? CAPTION_1 : CAPTION_2);
}
//  Для создания класса его необходимо зарегистрировать.
//  FUNCTION: MyRegisterClass()
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    wcex.cbSize         = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW;  //стиль окна
    wcex.lpfnWndProc    = WndProc;//адрес функции обработки сообщений.
    wcex.cbClsExtra     = 0; // число освобождаемых байтов в конце структуры
    wcex.cbWndExtra     = 0; // число освобождаемых байтов при создании экземпляра приложения
    wcex.hInstance      = hInstance;//дискриптор экземпляра приложения
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LAB6));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);//загрузка курсора
    wcex.hbrBackground  = (HBRUSH)GetStockObject(COLOR_3DFACE); // дескриптор кисти для закраски фона окна
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_LAB6);
    wcex.lpszClassName  = CLASS_NAME; //название класса
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    return RegisterClassEx(&wcex);//регистрация класса
}
 
//создание главного окна
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance;
 
    hWnd = CreateWindow// не расширенное окно(без EX)
        (CLASS_NAME,//имя класса для создаваемого окна (это имя использовалось при регистрации класса).
        bSecondInstance ? CAPTION_2 : CAPTION_1,//имя окна.
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,//стиль окна.
        CW_USEDEFAULT, 0, //позиция x,y
        300, 500,//ширина и высота
        NULL,// используется для создания «дочернего окна»
        NULL,//описатель меню
        hInstance, //экземпляр приложения.
        NULL);// указатель на пользовательский параметр окна.
 
    // если окно не создано
    if (!hWnd)
        return FALSE;
 
    ShowWindow(hWnd, nCmdShow);//функция показа окна
    UpdateWindow(hWnd);// если что-то добавили то обновляем
    return TRUE;
}
 
    
void ReceiveMessage(HWND hEdit, const char *msg)
{
    size_t src_text_len = GetWindowTextLength(hEdit);
    size_t full_len = src_text_len + strlen(msg) + 5;
    char *fulltext = (char*)malloc(full_len);
 
    if (src_text_len > 0)
    {
        GetWindowText(hEdit, fulltext, full_len);
        strcat_s(fulltext, full_len, "\r\n");
    }
    else
    {
        fulltext[0] = 0;
    }
 
    strcat_s(fulltext, full_len, ">>");
    strcat_s(fulltext, full_len, msg);
 
    SetWindowText(hEdit, fulltext);
 
    free(fulltext);
}
 
void SendTextMessage(HWND hMyWnd, HWND hEdit)
{
    HWND hOtherWnd = FindWindow(NULL, bSecondInstance ? CAPTION_1 : CAPTION_2);
    COPYDATASTRUCT cds;
 
    if (!hOtherWnd)
    {
        MessageBox(hMyWnd, "Нету второго окна!", "Ошибка", MB_ICONEXCLAMATION);
        return;
    }
    int textlen = GetWindowTextLength(hEdit) + 1;
    if (textlen == 1)
    {
        MessageBox(hMyWnd, "Пустое сообщение!", "Ошибка", MB_ICONEXCLAMATION);
        return;
    }
    char *message = (char*)malloc(textlen);
    GetWindowText(hEdit, message, textlen);
    // 1 параметр -Идентификатоp окна 
    // 2 параметр - буфеp, пpинимающий стpоку.
    // 3 параметр -Размеp буфеpа
    cds.lpData = message;
    cds.cbData = textlen;
    cds.dwData = COPYDATA_MSG;
    SendMessage(hOtherWnd, WM_COPYDATA, (WPARAM)hMyWnd, (LPARAM)&cds);
    free(message);
}
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND hMsgEdit, hResponseEdit, hStatusEdit;
    PCOPYDATASTRUCT pCDS1, pCDS2;
    HWND hOtherWnd = FindWindow(NULL, bSecondInstance ? CAPTION_1 : CAPTION_2);
    switch (message)
    {
    case WM_CREATE:
        hResponseEdit = CREATE_EDIT(5, 10, 270, 100, ES_MULTILINE | WS_VSCROLL | ES_READONLY);
        hMsgEdit = CREATE_EDIT(5, 150, 270, 100, ES_MULTILINE);
        hStatusEdit = CREATE_EDIT(5, 300, 270, 50, ES_READONLY | IDB_ONLINE | IDB_DONOTBOTHER | IDB_BUSY | IDB_OUTOFPLACE);
        CREATE_BUTTON(58, 380, 160, 30, "Отправить", IDB_SEND);
        if (!hOtherWnd)
        {
            SetWindowText(hStatusEdit, TEXT(bSecondInstance ? CAPTION_1 : CAPTION_2 "\r\nНету в сети"));
        }
        else
        {
            SetWindowText(hStatusEdit, TEXT(bSecondInstance ? CAPTION_1 : CAPTION_2 "\r\nОнлайн"));
        }
        if (GetOtherClientHandle())
        {
            SendMessage(GetOtherClientHandle(), NULL, NULL, NULL);
        } 
        break;
    case WM_COPYDATA:
        pCDS1 = (PCOPYDATASTRUCT)lParam;
        pCDS2 = (PCOPYDATASTRUCT)lParam;
        if (pCDS1->dwData == COPYDATA_MSG)
        {
            ReceiveMessage(hResponseEdit, (LPCSTR)pCDS1->lpData);
        }
        else if (pCDS2->dwData == COPYDATA_MSG)
        {
            ReceiveMessage(hStatusEdit, (LPCSTR)pCDS2->lpData);
        }
    case WM_COMMAND:
        if (LOWORD(wParam) == IDB_ONLINE)
        {
            SetWindowText(hStatusEdit, TEXT("             Онлайн"));
            SendTextMessage(hWnd, hStatusEdit);
        }
        else if (LOWORD(wParam) == IDB_BUSY)
        {
            SetWindowText(hStatusEdit, TEXT("             Занят"));
        }
        else if (LOWORD(wParam) == IDB_OUTOFPLACE)
        {
            SetWindowText(hStatusEdit, TEXT("             Отошел"));
        }
        else if (LOWORD(wParam) == IDB_DONOTBOTHER)
        {
            SetWindowText(hStatusEdit, TEXT("         Не беспокоить"));
        }
        switch (LOWORD(wParam))
        {
        case IDB_SEND:
            case IDM_SENDMSG:
                SendTextMessage(hWnd, hMsgEdit);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;      
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
 
    return 0;
}
lab6.h
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
#pragma once
#pragma comment(lib,"ComCtl32.Lib")
 
#include "resource.h"
 
#define IDB_SEND    1001
#define IDB_ONLINE          10001
#define IDB_DONOTBOTHER     10002
#define IDB_OUTOFPLACE      10003
#define IDB_BUSY            10004
 
 
#define CREATE_EDIT(x, y, w, h, style) CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | style, x, y, w, h, hWnd, NULL, hInst, NULL)
#define CREATE_BUTTON(x, y, w, h, text, id) CreateWindow("BUTTON", text, WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, x, y, w, h, hWnd, (HMENU)id, hInst, NULL)
 
#define COPYDATA_MSG        1
 
#define CAPTION_1   "chat1"
#define CAPTION_2   "chat2"
#define CLASS_NAME  "WindowClass"
#define SEND_BUTTON_ID      5000
#define MAX_TEXT_LENGTH     512
 
ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE hInstance, int nCmdShow);
void    ReceiveMessage(HWND hEdit, const char *msg);
HWND    GetOtherClientHandle();
void    SendTextMessage(HWND hMyWnd, HWND hEdit);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.12.2014, 10:52
Ответы с готовыми решениями:

WINAPI работа с окнами
Помогите пожалуйста разобраться с двумя проблемками... создаю окно следующим образом: procedure runproject; // действие по нажатию...

Оконное приложение WINAPI. Проблемы с гиперссылкой, диалоговыми окнами, таймером, и границы окна
1. Не отображается гиперссылка, она нигде не выскакивает (строки в коде 156 и 220); 2. Не отображаются окна добавления и удаления записей...

Переключение между окнами
Здравствуйте. Недавно начал изучать Qt. Создал 2 MainWindow окна (соответственно 2 ui файла и т.д.), называются они mainwindow и slots. В...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.12.2014, 10:52
Помогаю со студенческими работами здесь

Переход между окнами
Читая книгу по андройду и юзая AndroidStudio воздник вопрос* при создании нового проекта в андройде при указании формы BlankActivity ...

Взаемодействия между окнами
Здрасте. Есть приложение состоящее из нескольких модальных диалогов. Как наладить взаимодействие между этими диалогами? Как узнать hwnd...

Переключение между окнами
Всем привет! Вопрос такой. Вот, например взять Tab Widget, в нем заранее можно в каждом табе разместить свои Layout, в которые уже...

Переключение между окнами
Добрый вечер. Из основного окна открываю второстепенное и скрываю основное: private class PicActionListener implements MouseListener {...

Взаимодействие между окнами
В WinForms передавал нужные данные в качестве параметров при создании формы. Как грамотно делать это в WPF? Почитал Взаимодействие...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru