Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.51/41: Рейтинг темы: голосов - 41, средняя оценка - 4.51
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633

Петзольд. Тема DDE-(Dynamic Data Exchange)

03.11.2023, 16:35. Показов 10299. Ответов 93

Студворк — интернет-сервис помощи студентам
Здравствуйте! Не хочет работать программа из книги Петзольда. Тема, Dynamic Data Exchange, если честно, то саму тему не понял, соответственно, и ошибку найти не могу. Вот код:
Когда запускаю клиента, то бывает, что одно значение, численность штата меняется, а следом ошибка Failure on WM_DDE_ADVISE!, не знаю в чём дело.
Тут нужно выложит ещё и файлы ресурсов, но тогда когда будет совсем уж много, возможно, что кто-нибудь в теме разбирается и поможет, код то простой, если понимаешь что к чему, но если нужно выложу все файлы.

DDEPOP1 - Это сервер.
SHOWPOP1 - Это клиент.

DDEPOP1
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
//DDEPOP1.CPP
 
#include<windows.h>
#include<tchar.h>
 
#include<dde.h>
#include<string.h>
 
#include<stdio.h>
 
#include "ddepop1.h"
#include "..\..\..\..\..\Library\_my_header_files\RegisterClass\RegClass.h"
 
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ServerProc(HWND, UINT, WPARAM, LPARAM);
BOOL    CALLBACK TimerEnumProc(HWND, LONG);
BOOL    CALLBACK CloseEnumProc(HWND, LONG);
BOOL             PostDataMessage(HWND, HWND, int, BOOL, BOOL, BOOL);
 
const TCHAR szMainClass[] = TEXT("DdePop1");
const TCHAR szTitle[] = TEXT("DDE population server.");
 
HINSTANCE hInstance = NULL;
 
const TCHAR szServerName[] = TEXT("DdePop1.Server");
 
 
typedef struct
{
    unsigned int fAdvise : 1;
    unsigned int fDeferUpd : 1;
    unsigned int fAckReq : 1;
    unsigned int dummy : 13;
    long         lPopPrev;
} POPADVISE;
 
#define ID_TIMER           1 
#define ID_TIMEOUT         3000 
 
 
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,
    LPTSTR szCmdLine, int nCmdShow)
{
    hInstance = hInst;
    MSG msg = { 0 };
    HWND hwnd = NULL;
 
 
    RWC wc(hInst, WndProc, szMainClass); //Класс в котором происходит регистрация класса окна.
    wc.set_icon(hInst, szMainClass);
    if (!wc.reg_class())
        return FALSE;
 
    wc.set_wndproc(ServerProc);
    wc.set_wndextra(2 * sizeof(DWORD));
    wc.set_icon(NULL, IDI_APPLICATION);
    wc.set_class(szServerName);
    if (!wc.reg_class())
        return FALSE;
 
 
    if (!(hwnd = CreateWindow(szMainClass, szTitle,
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
        CW_USEDEFAULT, 0,
        CW_USEDEFAULT, 0,
        NULL, (HMENU)NULL, hInstance, NULL)))
    {
        return FALSE;
    }
 
    //Initialize 'pop' structure
    InitPops();
 
    SetTimer(hwnd, ID_TIMER, 5000, NULL);
 
 
    ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
    UpdateWindow(hwnd);
 
    for (; GetMessage(&msg, NULL, 0, 0);)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    KillTimer(hwnd, ID_TIMER);
    wc.unreg_class();
    //UnregisterClass(hInstance, szMainClass);
    return msg.wParam;
}
 
 
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static TCHAR szTopic[] = TEXT("US_Population");
    ATOM   aApp, aTop;
    HWND  hwndClient, hwndServer;
 
    switch (msg)
    {
    case WM_DDE_INITIATE:
    {
        //wParam          -- sending window handle
        //LOWORD(lParam)  -- application atom
        //HIWORD(lParam)  -- topic atom 
 
        hwndClient = (HWND)wParam;
        aApp = GlobalAddAtom(szMainClass);
        aTop = GlobalAddAtom(szTopic);
 
        //Check for matching atoms, create window, and acknowledge 
        if ((LOWORD(lParam) == NULL || LOWORD(lParam) == aApp) &&
            (HIWORD(lParam) == NULL || HIWORD(lParam) == aTop))
        {
            hwndServer = CreateWindow(szServerName, NULL,
                WS_CHILD, 0, 0, 0, 0,
                hwnd, NULL, hInstance, NULL);
            SetWindowLong(hwndServer, 0, (LONG)hwndClient);
            SendMessage((HWND)wParam, WM_DDE_ACK,
                (WPARAM)hwndServer, MAKELPARAM(aApp, aTop));
        }
        else  //Otherwise, delete the atoms just created
        {
            GlobalDeleteAtom(aApp);
            GlobalDeleteAtom(aTop);
        }
 
        return 0;
    }
    case WM_TIMER:
    case WM_TIMECHANGE:
    {
        //Calculate new current populations
 
        CalcPops();
 
        //Notify all child windows 
 
        EnumChildWindows(hwnd, &TimerEnumProc, 0L);
 
        return 0;
    }
    case WM_QUERYOPEN:
    {
        return 0;
    }
    case WM_CLOSE:
    {
        //Notify all child windows 
        EnumChildWindows(hwnd, &CloseEnumProc, 0L);
        break;  //for default processing
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
 
LRESULT CALLBACK ServerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    ATOM  aItem;
    TCHAR szItem[10];
    DDEACK DdeAck;
    DDEADVISE* pDdeAdvise;
    DWORD dwTime;
    GLOBALHANDLE hPopAdvise, hDdeAdvise, hCommands, hDdePoke;
    UINT uiLow, uiHi;
    HWND hwndClient;
    MSG iMsg;
    POPADVISE* pPopAdvise;
    WORD  cfFormat, wStatus;
 
    switch (msg)
    {
    case WM_CREATE:
    {
        //Allocate memory for POPADVISE structures
        hPopAdvise = GlobalAlloc(GHND, NUM_STATES * sizeof(POPADVISE));
        if (hPopAdvise == NULL)
            DestroyWindow(hwnd);
        else
            SetWindowLong(hwnd, 4, (LONG)hPopAdvise);
 
        return 0;
    }
    case WM_DDE_REQUEST:
    {
        //wParam            -- sending window handle 
        //LOWORD(lParam)    -- data format
        //HIWORD(lParam)    -- item atom 
 
        hwndClient = (HWND)wParam;
        cfFormat = LOWORD(lParam);
        aItem = HIWORD(lParam);
 
        //Check for matching format and data item
        if (cfFormat == CF_UNICODETEXT)
        {
            GlobalGetAtomName(aItem, szItem, sizeof(szItem));
            int i;
            for (i = 0; i < NUM_STATES; ++i)
                if (_tcscmp(szItem, pop[i].szState) == 0)
                    break;
 
            if (i < NUM_STATES)
            {
                GlobalDeleteAtom(aItem);
                PostDataMessage(hwnd, hwndClient, i,
                    FALSE, FALSE, TRUE);
                return 0;
            }
        }
 
        //Negative acknowledge if no match 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            GlobalDeleteAtom(aItem);
        }
 
        return 0;
    }
    case WM_DDE_ADVISE:
    {
        //wParam   --  sending window handle
        //lParam   --  DDEADVISE memory handle & item atom 
 
        UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLow, &uiHi);
        FreeDDElParam(WM_DDE_ADVISE, lParam);
 
        hwndClient = (HWND)wParam;
        hDdeAdvise = (GLOBALHANDLE)uiLow;
        aItem = (ATOM)uiHi;
 
        pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
        if (!pDdeAdvise)
        {
            MessageBox(hwnd, TEXT("Can't memory alloc 'GlobalLock'"),
                TEXT("ERROR: DDEPOP1 --> WM_DDE_ADVISE"),
                MB_OK | MB_ICONSTOP);
            return 0;
        }
        //Check for matching format and data item
        if (pDdeAdvise->cfFormat == CF_UNICODETEXT)
        {
            GlobalGetAtomName(aItem, szItem, sizeof(szItem));
            int i;
            for (i = 0; i < NUM_STATES; ++i)
                if (_tcscmp(szItem, pop[i].szState) == 0)
                    break;
 
            //Fill in the POPADVISE structure and acknowledge 
            if (i < NUM_STATES)
            {
                hPopAdvise = (GLOBALHANDLE)GetWindowLong(hwnd, 4);
                pPopAdvise = (POPADVISE*)GlobalLock(hPopAdvise);
 
                if (!pPopAdvise)
                {
                    MessageBox(hwnd, TEXT("Can't memory alloc 'GlobalLock'"),
                        TEXT("ERROR: DDEPOP1 --> WM_DDE_ADVISE"),
                        MB_OK | MB_ICONSTOP);
                    return 0;
                }
 
                pPopAdvise[i].fAdvise = TRUE;
                pPopAdvise[i].fDeferUpd = pDdeAdvise->fDeferUpd;
                pPopAdvise[i].fAckReq = pDdeAdvise->fAckReq;
                //pPopAdvise[i].fAckReq = pDdeAdvise->fAckReq;
                pPopAdvise[i].lPopPrev = pop[i].lPop;
 
                GlobalUnlock(hDdeAdvise);
                GlobalFree(hDdeAdvise);
 
                DdeAck.bAppReturnCode = 0;
                DdeAck.reserved = 0;
                DdeAck.fBusy = FALSE;
                DdeAck.fAck = TRUE;
 
                wStatus = *((WORD*)&DdeAck);
 
                if (!PostMessage(hwndClient, WM_DDE_ACK,
                    (WPARAM)hwnd,
                    PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
                {
                    GlobalDeleteAtom(aItem);
                }
                else
                {
                    PostDataMessage(hwnd, hwndClient, i,
                        pPopAdvise[i].fDeferUpd,
                        pPopAdvise[i].fAckReq,
                        FALSE);
                }
                GlobalUnlock(hPopAdvise);
                return 0;
            }
 
        }
        //Otherwise, post a negative WM_DDE_ACK 
        GlobalUnlock(hDdeAdvise);
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK,
            (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            GlobalFree(hDdeAdvise);
            GlobalDeleteAtom(aItem);
        }
 
        return 0;
    }
    case WM_DDE_UNADVISE:
    {
        //wParam           -- sending window handle 
        //LOWORD(lParam)   -- data format 
        //HIWORD(lParam)   -- item atom
        hwndClient = (HWND)wParam;
        cfFormat = LOWORD(lParam);
        aItem = HIWORD(lParam);
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = TRUE;
 
        hPopAdvise = (GLOBALHANDLE)GetWindowLong(hwnd, 4);
        pPopAdvise = (POPADVISE*)GlobalLock(hPopAdvise);
 
        //Check for matching format and data item
        if (cfFormat == CF_UNICODETEXT || cfFormat == NULL)
        {
            if (aItem == (ATOM)NULL)
                for (int i = 0; i < NUM_STATES; ++i)
                    pPopAdvise[i].fAdvise = FALSE;
            else
            {
                GlobalGetAtomName(aItem, szItem, sizeof(szItem));
                int i;
                for (i = 0; i < NUM_STATES; ++i)
                    if (_tcscmp(szItem, pop[i].szState) == 0)
                        break;
 
                if (i < NUM_STATES)
                    pPopAdvise[i].fAdvise = FALSE;
                else
                    DdeAck.fAck = FALSE;
            }
        }
        else
            DdeAck.fAck = FALSE;
 
        //Acknowledge either positively or negatively
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            if (aItem != (ATOM)NULL)
                GlobalDeleteAtom(aItem);
        }
 
        GlobalUnlock(hPopAdvise);
 
        return 0;
    }
    case WM_DDE_EXECUTE:
    {
        //Post negative acknowledge 
        hwndClient = (HWND)wParam;
        hCommands = (GLOBALHANDLE)lParam;
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus,
                (UINT)hCommands)))
        {
            GlobalFree(hCommands);
        }
        return 0;
    }
    case WM_DDE_POKE:
    {
        //Post negative acknowledge 
        UnpackDDElParam(WM_DDE_POKE, lParam, &uiLow, &uiHi);
        FreeDDElParam(WM_DDE_POKE, lParam);
        hwndClient = (HWND)wParam;
        hDdePoke = (GLOBALHANDLE)uiLow;
        aItem = (ATOM)uiHi;
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            GlobalFree(hDdePoke);
            GlobalDeleteAtom(aItem);
        }
        return 0;
    }
    case WM_DDE_TERMINATE:
    {
        //Respond with another WM_DDE_TERMINATE msg 
        hwndClient = (HWND)wParam;
        PostMessage(hwndClient, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
        DestroyWindow(hwnd);
        return 0;
    }
    case WM_TIMER:
    {
        //Post WM_DDE_DATA msgs for changed populations 
        hwndClient = (HWND)GetWindowLong(hwnd, 0);
        hPopAdvise = (GLOBALHANDLE)GetWindowLong(hwnd, 4);
        pPopAdvise = (POPADVISE*)GlobalLock(hPopAdvise);
 
        for (int i = 0; i < NUM_STATES; ++i)
            if (pPopAdvise[i].fAdvise)
                if (pPopAdvise[i].lPopPrev != pop[i].lPop)
                {
                    if (!PostDataMessage(hwnd, hwndClient, i,
                        pPopAdvise[i].fDeferUpd,
                        pPopAdvise[i].fAckReq,
                        FALSE))
                        {
                        //pPopAdvise[i].lPopPrev = pop[i].lPop;
                        break;
                        }
 
                    pPopAdvise[i].lPopPrev = pop[i].lPop;
                }
        GlobalUnlock(hPopAdvise);
        return 0;
    }
    case WM_CLOSE:
    {
        //Post a WM_DDE_TERMINATE msg to the client 
        hwndClient = (HWND)GetWindowLong(hwnd, 0);
        PostMessage(hwndClient, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
 
        dwTime = GetCurrentTime();
        while (GetCurrentTime() - dwTime < ID_TIMEOUT)
        {
            if (PeekMessage(&iMsg, hwnd, WM_DDE_TERMINATE,
                WM_DDE_TERMINATE, PM_REMOVE))
                break;
        }
        DestroyWindow(hwnd);
        return 0;
    }
    case WM_DESTROY:
    {
        hPopAdvise = (GLOBALHANDLE)GetWindowLong(hwnd, 4);
        GlobalFree(hPopAdvise);
        return 0;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
 
BOOL CALLBACK TimerEnumProc(HWND hwnd, LPARAM lParam)
{
    SendMessage(hwnd, WM_TIMER, 0, 0L);
    return TRUE;
}
 
BOOL CALLBACK CloseEnumProc(HWND hwnd, LPARAM lParam)
{
    SendMessage(hwnd, WM_CLOSE, 0, 0L);
    return TRUE;
}
 
BOOL PostDataMessage(HWND hwndServer, HWND hwndClient, int iState,
    BOOL fDeferUpd, BOOL fAckReq, BOOL fResponse)
{
    ATOM aItem;
    TCHAR szPopulation[16];
    DDEACK  DdeAck;
    DDEDATA* pDdeData;
    DWORD dwTime;
    GLOBALHANDLE hDdeData;
    MSG msg;
    WORD wStatus;
 
    aItem = GlobalAddAtom(pop[iState].szState);
 
    //Allocate a DDEDATA structure if not deferred update
 
    if (fDeferUpd)
    {
        hDdeData = NULL;
    }
    else
    {
        _stprintf_s(szPopulation, 16, TEXT("%ld\r\n"), pop[iState].lPop);
        hDdeData = GlobalAlloc(GHND | GMEM_DDESHARE,
            sizeof(DDEDATA) + (_tcslen(szPopulation)));
        pDdeData = (DDEDATA*)GlobalLock(hDdeData);
        if (!pDdeData)
            return FALSE;
 
 
        pDdeData->fResponse = fResponse;
        pDdeData->fRelease = TRUE;
        pDdeData->fAckReq = fAckReq;
        pDdeData->cfFormat = CF_UNICODETEXT;
 
        _tcscpy_s((PTSTR)pDdeData->Value, 16, szPopulation);
 
        GlobalUnlock(hDdeData);
    }
 
    //Post the WM_DDE_DATA msg 
    if (!PostMessage(hwndClient, WM_DDE_DATA, (WPARAM)hwndServer,
        PackDDElParam(WM_DDE_DATA, (UINT)hDdeData, aItem)))
    {
        if (hDdeData != NULL)
            GlobalFree(hDdeData);
 
        GlobalDeleteAtom(aItem);
        return FALSE;
    }
 
    //Wait for the acknowledge msg if it's requested 
    if (fAckReq)
    {
        DdeAck.fAck = FALSE;
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < ID_TIMEOUT)
        {
            if (PeekMessage(&msg, hwndServer, WM_DDE_ACK, WM_DDE_ACK,
                PM_REMOVE))
            {
                wStatus = LOWORD(msg.lParam);
                DdeAck = *((DDEACK*)&wStatus);
                aItem = HIWORD(msg.lParam);
                GlobalDeleteAtom(aItem);
                break;
            }
        }
        if (DdeAck.fAck == FALSE)
        {
            if (hDdeData != NULL)
                GlobalFree(hDdeData);
            return FALSE;
        }
    }
    return TRUE;
}



SHOWPOP1
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
//SHOWPOP1.CPP
 
#include<windows.h>
#include<tchar.h>
 
#include<dde.h>
#include<string.h>
 
#include "showpop1.h"
 
#include "D:\\Library\_my_header_files\RegisterClass\RegClass.h"
BOOL RegClass(WNDPROC, LPCTSTR, UINT);
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
 
const TCHAR szMainClass[] = TEXT("ShowPop1");
const TCHAR szTitle[] = TEXT("DDE Client - US population.");
 
HINSTANCE hInstance = NULL;
 
#define WM_USER_INITIATE   (WM_USER + 1) 
#define DDE_TIMEOUT        3000 
 
 
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,
    LPTSTR szCmdLine, int nCmdShow)
{
    hInstance = hInst;
    MSG msg = { 0 };
    HWND hwnd = NULL;
 
    //if(!RegClass(WndProc, szMainClass, COLOR_WINDOW))
        //return FALSE;
 
    RWC wc(hInst, WndProc, szMainClass);
    wc.set_icon(hInst, szMainClass);
    if (!wc.reg_class())
        return FALSE;
 
 
 
    if (!(hwnd = CreateWindow(szMainClass, szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0,
        CW_USEDEFAULT, 0,
        NULL, (HMENU)NULL, hInstance, NULL)))
    {
        return FALSE;
    }
 
 
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
 
    SendMessage(hwnd, WM_USER_INITIATE, 0, 0L);
 
    for (; GetMessage(&msg, NULL, 0, 0);)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
 
    wc.unreg_class();
    //UnregisterClass(hInstance, szMainClass);
    return msg.wParam;
}
 
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static BOOL fDoingInitiate = TRUE;
    static TCHAR szServerApp[] = TEXT("DdePop1"),
        szTopic[] = TEXT("US_Population");
    static char szServerAppA[] = "DdePop1",
        szTopicA[] = "US_Population";
    static HWND hwndServer = NULL;
    static long cxChar, cyChar;
    ATOM   aApp, aTop, aItem;
    TCHAR  szBuffer[24], szPopulation[16], szItem[16];
    DDEACK DdeAck;
    DDEDATA* pDdeData;
    DDEADVISE* pDdeAdvise;
    DWORD dwTime;
    GLOBALHANDLE hDdeAdvise, hDdeData;
    MSG iMsg;
    WORD wStatus;
 
    switch (msg)
    {
    case WM_CREATE:
    {
        TEXTMETRIC tm;
        HDC hdc = GetDC(hwnd);
        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cyChar = tm.tmHeight + tm.tmExternalLeading;
 
        ReleaseDC(hwnd, hdc);
        return 0;
    }
    case WM_USER_INITIATE:
    {
        //Broadcast WM_DDE_INITIATE iMsg
        aApp = GlobalAddAtom(szServerApp);
        aTop = GlobalAddAtom(szTopic);
 
        SendMessage(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwnd,
            MAKELONG(aApp, aTop));
 
        //If no response, try loading DDEPOP first
        if (hwndServer == NULL)
        {
            WinExec(szServerAppA, SW_SHOWMINNOACTIVE);
            SendMessage(HWND_BROADCAST, WM_DDE_INITIATE,
                (WPARAM)hwnd, MAKELONG(aApp, aTop));
        }
 
        //Delete the atoms 
        GlobalDeleteAtom(aApp);
        GlobalDeleteAtom(aTop);
        fDoingInitiate = FALSE;
 
        //If still no response, display message box 
 
        if (hwndServer == NULL)
        {
            MessageBox(hwnd,
                TEXT("Cannot connect with DDEPOP1.EXE!"),
                szMainClass, MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
 
        //Post WM_DDE_ADVISE iMsgs
        int i;
        for (i = 0; i < NUM_STATES; ++i)
        {
            hDdeAdvise = GlobalAlloc(GHND | GMEM_DDESHARE,
                sizeof(DDEADVISE));
            if (!hDdeAdvise)
            {
                MessageBox(hwnd,
                    TEXT("Can't memory alloc 'GlobalAlloc'"),
                    szMainClass, MB_OK);
                return 0;
            }
            pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
            if (!pDdeAdvise)
            {
                MessageBox(hwnd,
                    TEXT("Can't memory alloc 'GlobalLock'"),
                    szMainClass, MB_OK);
                return 0;
            }
            pDdeAdvise->fAckReq = TRUE;
            pDdeAdvise->fDeferUpd = FALSE;
            pDdeAdvise->cfFormat = CF_UNICODETEXT;
 
            GlobalUnlock(hDdeAdvise);
 
            aItem = GlobalAddAtom(pop[i].szAbb);
 
            if (!PostMessage(hwndServer, WM_DDE_ADVISE,
                (WPARAM)hwnd,
                PackDDElParam(WM_DDE_ADVISE,
                    (UINT)hDdeAdvise, aItem)))
            {
                GlobalFree(hDdeAdvise);
                GlobalDeleteAtom(aItem);
                break;
            }
            DdeAck.fAck = FALSE;
 
            dwTime = GetCurrentTime();
 
            while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
            {
                if (PeekMessage(&iMsg, hwnd, WM_DDE_ACK,
                    WM_DDE_ACK, PM_REMOVE))
                {
                    GlobalDeleteAtom(HIWORD(iMsg.lParam));
 
                    wStatus = LOWORD(iMsg.lParam);
 
                    DdeAck = *((DDEACK*)&wStatus);
 
                    if (DdeAck.fAck == FALSE)
                    {
                        GlobalFree(hDdeAdvise);
                    }
                    break;
                }
            }
 
            if (DdeAck.fAck == FALSE)
                break;
 
            while (PeekMessage(&iMsg, hwnd, WM_DDE_FIRST,
                WM_DDE_LAST, PM_REMOVE))
            {
                DispatchMessage(&iMsg);
            }
        }
        if (i < NUM_STATES)
        {
            MessageBox(hwnd, TEXT("Failure on WM_DDE_ADVISE!"),
                szMainClass, MB_ICONEXCLAMATION | MB_OK);
        }
        return 0;
    }
    case WM_DDE_ACK:
    {
        //In response to WM_DDE_INITIATE, save server window 
        unsigned int uiLow, uiHi;
        if (fDoingInitiate)
        {
            UnpackDDElParam(WM_DDE_ACK, lParam, &uiLow, &uiHi);
            if (!FreeDDElParam(WM_DDE_ACK, lParam))
            {
                DWORD er = GetLastError();
                DWORD eer = er;
            }
            hwndServer = (HWND)wParam;
            GlobalDeleteAtom((ATOM)uiLow);
            GlobalDeleteAtom((ATOM)uiHi);
        }
        return 0;
    }
    case WM_DDE_DATA:
    {
        //wParam  -- sending window handle
        //lParam  -- DDEDATA memory handle & item atom
        unsigned int uiLow, uiHi;
        UnpackDDElParam(WM_DDE_DATA, lParam, &uiLow, &uiHi);
        FreeDDElParam(WM_DDE_DATA, lParam);
 
        hDdeData = (GLOBALHANDLE)uiLow;
        pDdeData = (DDEDATA*)GlobalLock(hDdeData);
        aItem = (ATOM)uiHi;
 
        //Initialize DdeAck structure 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        //Check for matching format and data item 
        if (pDdeData->cfFormat == CF_UNICODETEXT)
        {
            GlobalGetAtomName(aItem, szItem, sizeof(szItem));
            int i;
            for (i = 0; i < NUM_STATES; ++i)
                if (_tcscmp(szItem, pop[i].szAbb) == 0)
                    break;
 
            if (i < NUM_STATES)
            {
                _tcscpy_s(szPopulation, 16, (TCHAR*)pDdeData->Value);
                pop[i].lPop = _tstol(szPopulation);
                InvalidateRect(hwnd, NULL, FALSE);
 
                DdeAck.fAck = TRUE;
            }
        }
 
        //Acknowledge if necessary
        if (pDdeData->fAckReq == TRUE)
        {
            wStatus = *((WORD*)&DdeAck);
            if (!PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd,
                PackDDElParam(WM_DDE_ACK, wStatus,
                    aItem)))
            {
                GlobalDeleteAtom(aItem);
                GlobalUnlock(hDdeData);
                GlobalFree(hDdeData);
                return 0;
            }
        }
        else
        {
            GlobalDeleteAtom(aItem);
        }
 
        //Clean Up
        if (pDdeData->fRelease == TRUE || DdeAck.fAck == FALSE)
        {
            GlobalUnlock(hDdeData);
            GlobalFree(hDdeData);
        }
        else
        {
            GlobalUnlock(hDdeData);
        }
        return 0;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
 
        int x, y;
        for (int i = 0; i < NUM_STATES; ++i)
        {
            if (i < (NUM_STATES + 1) / 2)
            {
                x = cxChar;
                y = i * cyChar;
            }
            else
            {
                x = 44 * cxChar;
                y = (i - (NUM_STATES + 1) / 2) * cyChar;
            }
 
            TextOut(hdc, x, y, szBuffer,
                _stprintf_s(szBuffer, 24, TEXT("%-20s"),
                    (PTSTR)pop[i].szState));
            x += 36 * cxChar;
 
            SetTextAlign(hdc, TA_RIGHT | TA_TOP);
 
            TextOut(hdc, x, y, szBuffer,
                _stprintf_s(szBuffer, 24, TEXT("%10ld"),
                    pop[i].lPop));
            SetTextAlign(hdc, TA_LEFT | TA_TOP);
        }
        EndPaint(hwnd, &ps);
        return 0;
    }
    case WM_DDE_TERMINATE:
    {
        //Respond with another WM_DDE_TERMINATE iMsg 
        PostMessage(hwndServer, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
        hwndServer = NULL;
        return 0;
    }
    case WM_CLOSE:
    {
        if (hwndServer == NULL)
            break;
 
        //Post WM_DDE_UNADVISE iMsg
        PostMessage(hwndServer, WM_DDE_UNADVISE, (WPARAM)hwnd,
            MAKELONG(CF_UNICODETEXT, NULL));
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
        {
            if (PeekMessage(&iMsg, hwnd, WM_DDE_ACK, WM_DDE_ACK,
                PM_REMOVE))
                break;
        }
 
        //Post WM_DDE_TERMINATE iMsg 
        PostMessage(hwndServer, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
        {
            if (PeekMessage(&iMsg, hwnd, WM_DDE_TERMINATE,
                WM_DDE_TERMINATE, PM_REMOVE))
                break;
        }
        break; //for default processing
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}



В этом участке кода ошибка:
Кликните здесь для просмотра всего текста
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
case WM_USER_INITIATE:
    {
        //Broadcast WM_DDE_INITIATE iMsg
        aApp = GlobalAddAtom(szServerApp);
        aTop = GlobalAddAtom(szTopic);
 
        SendMessage(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwnd,
            MAKELONG(aApp, aTop));
 
        //If no response, try loading DDEPOP first
        if (hwndServer == NULL)
        {
            WinExec(szServerAppA, SW_SHOWMINNOACTIVE);
            SendMessage(HWND_BROADCAST, WM_DDE_INITIATE,
                (WPARAM)hwnd, MAKELONG(aApp, aTop));
        }
 
        //Delete the atoms 
        GlobalDeleteAtom(aApp);
        GlobalDeleteAtom(aTop);
        fDoingInitiate = FALSE;
 
        //If still no response, display message box 
 
        if (hwndServer == NULL)
        {
            MessageBox(hwnd,
                TEXT("Cannot connect with DDEPOP1.EXE!"),
                szMainClass, MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
 
        //Post WM_DDE_ADVISE iMsgs
        int i;
        for (i = 0; i < NUM_STATES; ++i)
        {
            hDdeAdvise = GlobalAlloc(GHND | GMEM_DDESHARE,
                sizeof(DDEADVISE));
            if (!hDdeAdvise)
            {
                MessageBox(hwnd,
                    TEXT("Can't memory alloc 'GlobalAlloc'"),
                    szMainClass, MB_OK);
                return 0;
            }
            pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
            if (!pDdeAdvise)
            {
                MessageBox(hwnd,
                    TEXT("Can't memory alloc 'GlobalLock'"),
                    szMainClass, MB_OK);
                return 0;
            }
            pDdeAdvise->fAckReq = TRUE;
            pDdeAdvise->fDeferUpd = FALSE;
            pDdeAdvise->cfFormat = CF_UNICODETEXT;
 
            GlobalUnlock(hDdeAdvise);
 
            aItem = GlobalAddAtom(pop[i].szAbb);
 
            if (!PostMessage(hwndServer, WM_DDE_ADVISE,
                (WPARAM)hwnd,
                PackDDElParam(WM_DDE_ADVISE,
                    (UINT)hDdeAdvise, aItem)))
            {
                GlobalFree(hDdeAdvise);
                GlobalDeleteAtom(aItem);
                break;
            }
            DdeAck.fAck = FALSE;
 
            dwTime = GetCurrentTime();
 
            while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
            {
                if (PeekMessage(&iMsg, hwnd, WM_DDE_ACK,
                    WM_DDE_ACK, PM_REMOVE))
                {
                    GlobalDeleteAtom(HIWORD(iMsg.lParam));
 
                    wStatus = LOWORD(iMsg.lParam);
 
                    DdeAck = *((DDEACK*)&wStatus);
 
                    if (DdeAck.fAck == FALSE)
                    {
                        GlobalFree(hDdeAdvise);
                    }
                    break;
                }
            }
 
            if (DdeAck.fAck == FALSE)
                break;
 
            while (PeekMessage(&iMsg, hwnd, WM_DDE_FIRST,
                WM_DDE_LAST, PM_REMOVE))
            {
                DispatchMessage(&iMsg);
            }
        }
        if (i < NUM_STATES) //Здесь она сообщает, что что-то не так. 
        {
                    
            MessageBox(hwnd, TEXT("Failure on WM_DDE_ADVISE!"),
                szMainClass, MB_ICONEXCLAMATION | MB_OK);
        }
        return 0;
    }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.11.2023, 16:35
Ответы с готовыми решениями:

Чем заменить Dynamic Data Exchange (DDE) из VB6
Здравствуйте. На vb6 очень удобная вещь - Dynamic Data Exchange (DDE) для обмена данными между приложениями, на vb2005 уже не...

научите пользоваться Dynamic Data Display
прошу научите) с самого начала! -как добавить библиотеку в проект? -появятся ли контролы какие-то или нет? (простите возможно это...

Отображение графика в Dynamic Data Display
Добрый день. Не могу добиться отображения данных на графике. P.S. Plotter.AddLineGraph отказывается работать P.P.S. c#...

93
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
12.11.2023, 00:33  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от politoto Посмотреть сообщение
Кто, кроме Вас, может знать, что делает программа, полученная из текста, в котором есть подобные строчки?
Я же пояснял этот код - это регистрация окна и не более.

Цитата Сообщение от politoto Посмотреть сообщение
А чего Вы ожидали, и как всё должно работать?
Должно показывать количество населения в каждом населённом пункте.

Цитата Сообщение от politoto Посмотреть сообщение
Проще сделать свою программу для ЭВМ, чем модернизировать эту иллюстрацию для книжки.
Цитата Сообщение от politoto Посмотреть сообщение
Или напрограммируйте свой пример
Если бы я знал как это сделать я уже давно бы это продемонстрировал, но я не понимаю как(не разобрался в теме), а документация, да ещё в машинном переводе, тот ещё помощник.

Цитата Сообщение от politoto Посмотреть сообщение
GMEM_DDESHARE
GMEM_DISCARDABLE
GMEM_LOWER
Вместо этих значений нужно устанавливать что, GHND, так как оно объединяет GMEM_MOVEABLE и GMEM_ZEROINIT?
hDdeAdvise = GlobalAlloc(GHN, sizeof(DDEADVISE)); или просто hDdeAdvise = GlobalAlloc(GMEM_MOVEABLE sizeof(DDEADVISE));...

Цитата Сообщение от politoto Посмотреть сообщение
Это же мат.модель.
Мат.модель чего?
Цитата Сообщение от politoto Посмотреть сообщение
использовал простую линейную экстраполяцию, которая не уходит в минуса, если в известных точках показатели не убывают.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
12.11.2023, 07:21
Цитата Сообщение от Liss29 Посмотреть сообщение
Мат.модель чего?
Роста/убыли населения штатов.
Цитата Сообщение от Liss29 Посмотреть сообщение
не понимаю как(не разобрался в теме), а документация, да ещё в машинном переводе, тот ещё помощник.
Картинки в книжке Чарлза помогли?

Добавлено через 4 часа 17 минут
Liss29, если начать с чего-нибудь по-проще и понятнее, сможете создать папки в меню "Пуск" с помощью DDEML?
Что-нибудь вроде
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
#include <windows.h>
#include <ddeml.h>
 
HDDEDATA DdeCallback (WORD,WORD,HCONV,HSZ,HSZ,HDDEDATA,DWORD,DWORD) 
{    return 0;  }
 
int
main()
{
    DWORD idInst{0};
    UINT err { DdeInitializeW(&idInst,           // receives instance ID
            (PFNCALLBACK)DdeCallback,       // address of callback function
            APPCMD_CLIENTONLY, // this is a client app
            0L)         
        };                          
    
    if (DMLERR_NO_ERROR != err)
        return err;
 
    DWORD result{0};
    HSZ hszServTop { DdeCreateStringHandleW(idInst, L"PROGMAN", CP_WINUNICODE)};
 
    // attempt to start conversation with server app
    if (HCONV hconv { DdeConnect(idInst, hszServTop, hszServTop, NULL)})
    {
        {
        wchar_t Command[] {L"[CreateGroup(CyberForum.RU)]"};
        size_t byteLen {sizeof Command};
        DWORD dwResult{0};
        
            // send command to server app
            HDDEDATA hData = DdeClientTransaction((LPBYTE)Command, // data to pass
                byteLen,          // length of data
                hconv,             // handle of conversation
                NULL,              // handle of name-string
                CF_TEXT,           // clipboard format
                XTYP_EXECUTE,      // transaction type
                1000,              // timeout duration
                &dwResult);        // points to transaction result
 
            if (0 == hData || 0 ==  DdeFreeDataHandle(hData))
            result = DdeGetLastError(idInst);
        }
 
        {
            HSZ hszRequest { DdeCreateStringHandleW(idInst, L"Groups", CP_WINUNICODE)};
            DWORD dwResult{0};
 
            HDDEDATA hData = DdeClientTransaction(0, // data to pass
                0,          // length of data
                hconv,             // handle of conversation
                hszRequest,              // handle of name-string
                CF_TEXT,           // clipboard format
                XTYP_REQUEST,      // transaction type
                2000,              // timeout duration
                &dwResult);        // points to transaction result
            if (0 != hData ) 
            {
                DWORD DataSize{0};
                LPBYTE pb = DdeAccessData( hData, &DataSize );
                
                MessageBox(0, (char*)pb, "Groups", MB_OK );
                if ( 0 != pb )
                    DdeUnaccessData(hData);
            
                if( 0 ==  DdeFreeDataHandle(hData))
                    result = DdeGetLastError(idInst);
                
            } else result = DdeGetLastError(idInst);
        
            DdeFreeStringHandle(idInst, hszRequest);
        }       
        // end conversation
        DdeDisconnect(hconv);
    }
 
    // free service/topic string handle
    DdeFreeStringHandle(idInst, hszServTop);
 
    return result;
 
}
#pragma comment(lib,"user32")
И никаких GHND.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
12.11.2023, 08:15  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Картинки в книжке Чарлза помогли?
Нет, не помогли, но то что я читал на сайте майкрософта в переводе гораздо хуже изложено и уж точно куда менее понятно, чем у Питзольда, для меня это так... То что я не понял, ну что ж, я не один такой, мне это тема не далась.

Цитата Сообщение от politoto Посмотреть сообщение
если начать с чего-нибудь по-проще и понятнее, сможете создать папки в меню "Пуск" с помощью DDEML?
Я же про DDE спрашивал, а не про DDEML. Создать папку, серьёзно, с помощью DDE, это просто, да ладно, ну, я не понял как это сделать. В общих чертах это должно быть реализовано как-то так, клиент посылает запрос(команду), а сервер должен создать папку, если я всё правильно понимаю в этой теме. Так что это не проще. Да, и почему бы не заставить программу автора книги заработать, если вы в теме понимаете...
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
12.11.2023, 09:46
Цитата Сообщение от Liss29 Посмотреть сообщение
Я же про DDE спрашивал, а не про DDEML
DDEML это же стандартная реализация Windows протокола DDE.
Цитата Сообщение от Liss29 Посмотреть сообщение
почему бы не заставить программу автора книги заработать, если вы в теме понимаете...
Потому что цель примера из книги - не заработать, а показать, как использовать возможности DDE, описанные в соответствующей главе, в Win32 с помощью DDEML и без помощи.

Автор что-то зачем-то подправил в примере из предыдущих изданий книги для 16-разрядной Windows (без DDEML), Вы что-то подправили, возможно, переводчик что-то подправил, если Вы брали не исходный вариант. Какие-то исправления были в Microsoft KB, какие-то на официальном сайте книги, какие-то на других сайтах с разбором ошибок by Charles Petzold...

И мне не совсем ясно, какой правильный должен быть результат работы этих видоизменённых примеров.

Внутренняя реализация DDE в Win32 такая, какая она есть, только для того, чтобы сохранилась работоспособность 16-разрядных клиентов и серверов DDE, работающих в 16-разрядной подсистеме 32-разрядной Windows и взаимодействующих с 32-разрядными клиентами и серверами, в том числе с Проводником.

Если Вам ясно, как это должно работать, и как это протеститровать, и Вы хотите модернизировать старый пример без DDEML, то возможно, Вам лучше взять исходный 16-разрядный вариант из старых изданий.

Programming Windows "3.0" (1990, 2-е издание)
https://www.charlespetzold.com/src/ProgWin30.zip
\CHAP17\DDEPOP.C

Programming Windows "3.1" (1992, 3-е издание)
https://www.charlespetzold.com/src/ProgWin31.zip
\CHAP17\DDEPOP1.C

Открыть окошко с исходником с официального сайта автора, открыть окошко с https://learn.microsoft.com/en... a-exchange ,
и окошко со своим модернизированным сервером, и, сверяясь с официальной документацей, сделать свой аналог.
То, что функции и сообщения называются одинаково, совсем не значит что они одинаково работают, как Вы понимаете . Может быть, на RSDN, если он ещё жив, найдёте лучший человечный перевод статей из MSJ и KB по заинтересовавшей Вас теме.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
12.11.2023, 10:42  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Потому что цель примера из книги - не заработать, а показать, как использовать возможности DDE, описанные в соответствующей главе, в Win32 с помощью DDEML и без помощи.
Я об этом же и говорю, если я не могу заставить программу работать значит я суть главы не усвоил. Хотя изначально, казалось, что всё просто послал сообщение получил ответ, но нет, не всё так просто.
Например, зачем в программе сервер создаётся второе окно и, соответственно, вторая процедура, почему нельзя принимать и обрабатывать сообщения в процедуре основного окна, что-то не могу уловить мысль автора.

Цитата Сообщение от politoto Посмотреть сообщение
Автор что-то зачем-то подправил в примере из предыдущих изданий книги для 16-разрядной Windows (без DDEML), Вы что-то подправили, возможно, переводчик что-то подправил, если Вы брали не исходный вариант.
Первоначально я ничего не подправлял взял файлы из примеров и собрал приложение, всё. В примерах, есть готовые .exe-ки, но что касается приложений DDEPOP1, SHOWPOP1 они точно так же не работают, и выкидывают тоже предупреждение так что кто там что правил или не правил я не знаю, но явно, что кто-то всё это дело собрал, и, видимо, забыл проверить на работоспособность.

Цитата Сообщение от politoto Посмотреть сообщение
И мне не совсем ясно, какой правильный должен быть результат работы этих видоизменённых примеров.
И мне не ясно, но что-то подсказывает, что, как минимум, она точно не должна выкидывать предупреждений. И почему-то мне кажется, что она должна выводить числовые значения для каждого населённого пункта, а не для первого и, иногда, так же для второго.

Цитата Сообщение от politoto Посмотреть сообщение
и как это протеститровать
Нет, не ясно, как это протестировать и даже как отладить не имею представления...

Цитата Сообщение от politoto Посмотреть сообщение
Открыть окошко с исходником с официального сайта автора, открыть окошко с https://learn.microsoft.com/en... a-exchange ,
и окошко со своим модернизированным сервером, и, сверяясь с официальной документацей, сделать свой аналог.
Т.е. здесь помощи ждать не стоит, я правильно понимаю?!
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
12.11.2023, 11:18
Цитата Сообщение от Liss29 Посмотреть сообщение
здесь помощи ждать не стоит
Начните работу, задавайте вопросы, думаю, здесь помогут.

Пока настраиваетесь, можете поискать перевод одной из первых статей по раннему варианту DDE
(страница 7)

https://archive.org/download/m... 986-10.pdf
Цитата Сообщение от Liss29 Посмотреть сообщение
зачем в программе сервер создаётся второе окно и, соответственно, вторая процедура, почему нельзя принимать и обрабатывать сообщения в процедуре основного окна, что-то не могу уловить мысль автора.
Можно и первое не создавать в сервере.
DDEML вообще прячет служебное окно для обработки сообщений DDE от пользователя, и самому явно создавать его не нужно.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
12.11.2023, 11:33  [ТС]
Как вы думаете, нужно ли в сообщении клиента (SHOWPOP1) WM_USER_INITIATE в цикле выделять память для структуры DDEADVISE, не жирно ли? Или, всё же, это необходимость. Возможно, ошибка здесь, хотя я ставил проверки дескриптора и указателя на равенство нулю и ни одного MessageBox не получил.

сообщение WM_USER_INITIATE это:
Code
1
#define WM_USER_INITIATE (WM_USER + 1)
C++
1
2
3
4
5
6
7
8
9
10
11
12
for (i = 0; i < NUM_STATES; i++)
{
    hDdeAdvise = GlobalAlloc(GHND, sizeof(DDEADVISE));
    pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
    
    //-----
    pDdeAdvise->fAckReq   = TRUE;
    pDdeAdvise->fDeferUpd = FALSE;
    pDdeAdvise->cfFormat  = CF_TEXT;
    
    //........ 
}
Добавлено через 11 минут
Цитата Сообщение от politoto Посмотреть сообщение
Можно и первое не создавать в сервере.
Можно, но, если всё же окно создаётся, хоть и в функции ShowWindow устанавливается флаг SW_SHOWMINNOACTIVATE, это что качается главного окна, второе вообще не показывается. Что это за причины такие веские? Или это для задания нескольких серверов на базе одного приложения, скажем, есть главное окно с функцией WnProc и второе окно для сервера1 с
процедурой ServerProc1. Если серверов будет два, то добавится ещё одно окно с процедурой ServerProc2 и.т.д. или это чушь полная?
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
12.11.2023, 12:01
Цитата Сообщение от Liss29 Посмотреть сообщение
второе вообще не показывается. Что это за причины такие веские?
Это чтобы пользователь не помял и не проковырял мышкой окно, пока сервер обрабатывет транзакцию на зиллиарды пуказоидов. Смотрели картинки в статье?

Когда окно не видно, и оно не обрабатывает сообщения ни от мышки, ни от клавиатуры, то как-то спокойнее за его целостность.

Добавлено через 7 минут
Проще всего отказывать в обслуживании новым клиентам, пока текущий не завершил свой сеанс.
А что будет с сервером из книжки, если к нему подключатся два клиента?
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
12.11.2023, 12:09  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Смотрели картинки в статье?
В этой
Цитата Сообщение от politoto Посмотреть сообщение
https://archive.org/download/m... 986-10.pdf
, если да, то тут совсем всё другое, здесь даже структуры создают сами. Нужно читать, а там всё на буржуинском.

Цитата Сообщение от politoto Посмотреть сообщение
Когда окно не видно, и оно не обрабатывает сообщения ни от мышки, ни от клавиатуры, то как-то спокойнее за его целостность.
Окно клиента отображается да и главное окно сервера на панели задач присутствует пусть и в свёрнутом, минимизированном виде. Так что, если захочет остановить, остановит.

Добавлено через 2 минуты
Цитата Сообщение от politoto Посмотреть сообщение
А что будет с сервером из книжки, если к нему подключатся два клиента?
Не в курсе. Ошибку должен отобразить, сообщить о невозможности подключения нового клиента.
0
 Аватар для Наталья8
623 / 381 / 67
Регистрация: 09.03.2016
Сообщений: 4,231
12.11.2023, 14:56
Troll29,
В любой книжке информация стилизована под время написания оной.
Под условия автора - IDE... опер. система.
Это всё надо понимать и переводить под реальные условия.
Миниатюры
Петзольд. Тема DDE-(Dynamic Data Exchange)  
0
 Аватар для Наталья8
623 / 381 / 67
Регистрация: 09.03.2016
Сообщений: 4,231
12.11.2023, 15:39
Вот winApi.
А отнюдь не то дерьмо, которое вы от куда то выворачиваете.
Надеюсь с вашей начитанностью,
вам будет не трудно разобрать то, что я навставлял.


C++
1
2
3
4
5
#include <mmsystem.h>// Звук PlaySound
#pragma comment(lib, "winmm")// Звук
#include<vfw.h>
#include<mmeapi.h>
#pragma comment(lib, "Vfw32.lib")
==================== работа с папками и файлами

C++
1
2
3
4
5
6
SHFILEOPSTRUCT op;
    ZeroMemory(&op, sizeof(op));
    op.wFunc = FO_DELETE;//  FO_MOVE || FO_DELETE || FO_RENAME
        op.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_ALLOWUNDO;// Тихо и в корзину
 
    if (SHFileOperation(&op) == 0){ Beep(4000, 5); }
===================== поиск по фолдеру (можно и в подпапках поискать)

C++
1
2
3
4
HANDLE  const hFind = FindFirstFileW(Mask, &FindData);
} while (NULL != FindNextFileW(hFind, &FindData));
 
        FindClose(hFind);
=====================
C++
1
2
3
4
5
//---------------------------- Хитрым способом открыть папку и выделить последний полученный файл
            CoInitializeEx(0, COINIT_MULTITHREADED);
                ITEMIDLIST* dir = ILCreateFromPathA(video_dst_filename);
                        LPITEMIDLIST* items = new LPITEMIDLIST[1];
                        strcat(video_dst_filename, fl);// <--- Имя файла приклеить снова
=====================

C++
1
2
3
4
5
6
7
8
9
10
bool Set_Dialog(wchar_t *file_adr) {
    //================================ фолдер (диалог) есть ещё файл диалог.
    BROWSEINFO    binfo; 
    char          szDisplayName[MAX_PATH];
    LPITEMIDLIST  pidl;
    LPMALLOC      pShellMalloc;
    bool suscess{ false };
    if (SHGetMalloc(&pShellMalloc) == NO_ERROR)
    {// --------
        SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl);//здесь тип спец. папки вот здесь можно узнать
================================ владелец папки

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BOOL SetPrivilege(
    HANDLE hToken,          // access token handle
    LPCTSTR lpszPrivilege,  // name of privilege to enable/disable --- SE_TAKE_OWNERSHIP_NAME
    BOOL bEnablePrivilege) {
    TOKEN_PRIVILEGES tp;
    LUID luid;
 
    if (!LookupPrivilegeValue(
        NULL,            // lookup privilege on local system
        lpszPrivilege,   // privilege to lookup 
        &luid))        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError());
        return FALSE;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

C++
1
2
3
4
5
6
7
8
// Открытие дескриптора токена доступа для вызывающего процесса.
    if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES,
        &hToken))
    {
        printf("OpenProcessToken failed: %u\n", GetLastError());
        goto Cleanup;
    }
=====================

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
//-------------звукозапись ------------
#include "mmdeviceapi.h"
#include "audioclient.h"
#pragma comment(lib, "ole32.lib")
 
//===================================================
//     Stream    Писать ЗВУК вторым потоком
//===================================== входной параметр структура dataForAudio
DWORD WINAPI RecordAudioStream(void *param)
{
// REFERENCE_TIME time units per second and per millisecond
                                      #define REFTIMES_PER_SEC 10000000
                                            #define REFTIMES_PER_MILLISEC  10000
WAVEFORMATEX *pwfx = NULL;  
 
struct WAVHEADER
{/*
хрена
*/
  char chunkId[4]; //RIFF
    unsigned long chunkSize;
    char format[4]; //WAVE
  
    unsigned short blockAlign;
    unsigned short bitsPerSample;
    unsigned short cbSize;
};
 
const UINT WAVHEADER_SIZE = 38;
 
struct WAV_FACT_CHUNK
=====================

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Скриншот
_screen = new cv::Mat( height, width, CV_8UC3, data, step ); // - delete screen;
    }
~Screen(){
SelectObject( hScreen, hBM_Temp );
delete[] data; data = NULL;
}
       // ----- int _x, int _y  Координаты  
cv::Mat& get( int _x, int _y){ 
 //***************** BitBlt( hScreen - дескрипт. назначения
BitBlt( hScreen, 0, 0, width, height, hWDC, _x, _y, SRCCOPY | CAPTUREBLT);
//--------- Хуйня что бы было видно курсор (можно вырезать на хуй)
 CURSORINFO cursor;
cursor.cbSize=sizeof(CURSORINFO);
======================
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//------- Функция узнаёт размер кадра и меняет образцовый файл AVI ----******* Видео *************
void SaveSmall( LPCWSTR lpFilename,bool back,short &lp_x,short &lp_y , double &frame_per_s ) 
{   //  https://docs.microsoft.com/en-us/previous-versions/ms779632(v=vs.85)
    
 AVISTREAMINFO  strhdr; // AVISTREAMINFO
 BITMAPINFOHEADER  bi;
 BITMAPINFOHEADER biNew;
    PAVISTREAM  gapavi;
PAVISTREAM       psSmall; 
    PAVIFILE  pfile;
    PAVIFILE    pf;
    int gcpavi(0); 
       HRESULT  hr;
    LONG hr0;
     LONG  lStreamSize; 
   LPVOID           lpOld; 
    LPVOID           lpNew;
======================

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ============================ Обработчик невидимой формы под рамку из чёрточек (рамка над раб. столом)
 LRESULT CALLBACK wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
     hWnd_win = hWnd;
     HDC hdc;
     HPEN hPen3;  RECT rect;
     PAINTSTRUCT ps; //создаём экземпляр структуры графического вывода
     short width(Win_x + 5);// Размеры красивой рамки (Подбирать, что бы в кадре не было видно)
     short height(Win_y + 5); // Было плюс пять
     //  http://radiofront.narod.ru/htm/prog/htm/winda/api/paint.html#1 
     //-------------------------------------------- 
     switch (uMsg)
       {
     case WM_CREATE:
         break;
 
     case WM_ERASEBKGND:// Легко окрасил фон формы (фон введён в структуру)
         GetClientRect(hWnd, &rect);
         FillRect((HDC)wParam, &rect, CreateSolidBrush(RGB(255, 0, 255)));
          break;
Добавлено через 13 минут
Работа с процессами....
C++
1
2
3
4
5
6
7
8
9
10
//--------------------------------Узнать Есть ли процесс ???
 
DWORD IsProcessRunning(const TCHAR* const executableName, DWORD &ProcId) {
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);
 
    const auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
 
    if (!Process32First(snapshot, &entry)) {
        CloseHandle(snapshot);
========= Работа с буфером
C++
1
2
3
4
5
6
7
8
9
10
11
// Взять текст из клипбоард ( Вобьёт в массив текст из клипбоард, конвертированный в ANSI )
void get_txt_buffer(char* ret_param){
 
    std::string buf; int size(0);
    if (::OpenClipboard(NULL)) {
        HGLOBAL hGlobal = ::GetClipboardData(CF_UNICODETEXT);// Читает юникод
        if (hGlobal != NULL) {
            LPWSTR lpszData = (LPWSTR)::GlobalLock(hGlobal);
            if (lpszData != nullptr) {
                size = ::WideCharToMultiByte(CP_ACP, 0, lpszData, -1, nullptr, 0, nullptr, nullptr);
                if (size > 0) {// WideCharToMultiByte в зависимости от флага (CP_ACP - default ANSI или CP_UTF8)
Добавлено через 8 минут
РАБОТАТЬ НАДО
0
 Аватар для Наталья8
623 / 381 / 67
Регистрация: 09.03.2016
Сообщений: 4,231
12.11.2023, 15:42

Тоже winApi...
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
13.11.2023, 07:58
Цитата Сообщение от Liss29 Посмотреть сообщение
А указатели на word, которые присутствуют повсеместно в примере, возможно, правельнее будет приводить к указателю на dword или я не туда копаю?
wStatus = *((WORD*)&DdeAck);
Здесь wStatus побитово соответствует DdeAck.
В с++ 20 есть std::bit_cast, а универсальный способ - что-то вроде
C++
1
2
/*std::*/memcpy(&wStatus, &DdeAck, sizeof wStatus);
//static_assert((sizeof wStatus) == (sizeof DdeAck));
Самое лучшее, чего Вы можете добиться копипастой иллюстраций из книги и бессистемными правками - чудная программка, которая только чудом, наконец, заработает только на одной Вашей машине, а после очередного безобидного обновления системы работать перестанет.

Добавлено через 14 минут
Цитата Сообщение от Liss29 Посмотреть сообщение
суть главы не усвоил. Хотя изначально, казалось, что всё просто послал сообщение получил ответ, но нет, не всё так просто.
Например, зачем в программе сервер создаётся второе окно и, соответственно, вторая процедура, почему нельзя принимать и обрабатывать сообщения в процедуре основного окна, что-то не могу уловить мысль автора.
Возможно, автор изложил свои мысли в описании программы, которое вы при первом чтении пропустили или недоразобрали.

А то, что у Вас есть свои мысли о том, что можно сделать и по-другому, это ли не начало понимания сути?
Освоить суть можно в результате собственноручных экспериментов и собственного творчества. Попробуйте сделать по-своему, и тогда у Вас возникнут настоящие вопросы, а не гадание неизвестно о чём.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
14.11.2023, 10:08  [ТС]
В общем я добился того что программа заработала, но пришлось изменить значение поля fAckReq структуры pDdeAdvise в сообщении WM_USER_INITIATE приложения клиента. Первоначально у автора это значение установлено в TRUE, что требует подтверждения от клиента получения данных, если изменить этот флаг на FALSE, то всё работает как надо, кроме математических вычислений, но суть в том, как утверждает автор и в чём я убедился сам, что если задать полу fAckReq структуры pDdeAdvise значения FALSE т.е. не нужно отвечать серверу получил клиент данные или нет, и при этом изменить системное время, то сервер отправит сразу 52 сообщения WM_DDE_DATA, что приводит к переполнению очереди сообщений, вот цитата:
Первоначально, программа SHOWPOP1 была написана так, что она отправляла синхронные сообщения WM_DDE_ADVISE с полем fAckReq структуры DDEADVISE равным FALSE. Это показывало серверу, что ему нужно отправлять синхронные сообщения WM_DDE_DATA с полем fAckReq структуры DDEDATA равным FALSE, что, в свою очередь, показывало клиенту, что не нужно отправлять серверу синхронных сообщений WM_DDE_ACK, подтверждающих получение сообщений WM_DDE_DATA. Это хорошо работало при обычном обновлении данных. Однако, если во время работы программы SHOWPOP1 изменить системное время Windows,
то программа DDEPOP1 посылает программе SHOWPOP1 52 синхронных сообщения WM_DDE_DATA, не ожидая их подтверждения. Это приводило к переполнению очереди сообщений программы SHOWPOP1 и она теряла большую часть обновленных данных о населении.

Урок ясен: если клиент хочет, чтобы его извещали об изменении нескольких элементов данных одновременно, он
должен присвоить полю fAckReq структуры DDEADVISE значение TRUE. Это единственный безопасный вариант.
Так что нужно всё же устанавливать значение TRUE флагу fAckReq, но тогда приложение не хочет работать на windows 10, а вот в windows XP работает и с установленным в TRUE флагом fAckReq, и, если он установлен как FALSE. Правда, перед тем как отобразит информацию программа задумывается, чего нет в windows 10, возможно, это потому что windows XP я установил на виртуальную машину, 10-ка хост-машина. Но, если запускать приложение на хостовой машине, то она отрабатывает только если pDdeAdvise->fAckReq = FALSE; иначе не хочет. Как-то так.

Добавлено через 13 минут

Не по теме:

Цитата Сообщение от politoto Посмотреть сообщение
Здесь wStatus побитово соответствует DdeAck.
Только почему-то, если в DdeAck установлено в TRUE одно поле fAck, а все остальные установлены в 0, то wStatus присваивается значение 32768, а не, скажем, один. Понятно, что это максимальное возможное число для типа WORD, но всё же...

Цитата Сообщение от politoto Посмотреть сообщение
Возможно, автор изложил свои мысли в описании программы, которое вы при первом чтении пропустили или недоразобрали.
Возможно, но скорее всего дело в том, что мне чтобы точно понять(усвоить) материал нужно выполнять практические задания так мне легче усваивать теорию, не знаю почему и нормально ли это, но у меня это так.

Цитата Сообщение от politoto Посмотреть сообщение
Освоить суть можно в результате собственноручных экспериментов и собственного творчества. Попробуйте сделать по-своему, и тогда у Вас возникнут настоящие вопросы, а не гадание неизвестно о чём.
Пробую, но как-то неудачно:)



Добавлено через 10 минут

Не по теме:

Цитата Сообщение от Наталья8 Посмотреть сообщение
Тоже winApi...
Что это за winapi, такие чёткие окна создаёт?

1
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
14.11.2023, 11:53
Цитата Сообщение от Liss29 Посмотреть сообщение
добился того что программа заработала, но пришлось изменить значение поля fAckReq структуры pDdeAdvise в сообщении WM_USER_INITIATE приложения клиента.
Уважаемый Liss29, не могли бы Вы опубликовать исправленный и дополненный Вами вариант сервера и клиента?

Вдруг кому-нибудь ещё захочется заняться таким программированием по ретроучебникам.
1
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
14.11.2023, 12:27  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
не могли бы Вы опубликовать исправленный и дополненный Вами вариант сервера и клиента?
Да, почему бы и нет, запихал в архив так как там много кода, но могу и так выложить спрятав под спойлер, не знаю как лучше.
DDEPOP1.rar
1
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
14.11.2023, 12:44  [ТС]
politoto
Как вы думаете, всё же, почему в одной операционной системе приложение работает, а в другой, более современной, нет? Windows XP - работает, с любыми флагами, а Windows 10, нет, мне кажется, что это означает, что код написан верно, за исключением некоторых мелочей связанных с упаковкой-распаковкой данных, но в чём тогда дело, безопасность, скорость..., что?
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
14.11.2023, 13:44
Liss29, на Windows 10 Вы 64-разрядное приложение собирали?
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
14.11.2023, 14:03  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
на Windows 10 Вы 64-разрядное приложение собирали?
Нет, 32-х разрядное.

Добавлено через 8 минут
DDEPOP1.C
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
/*---------------------------------------------
   DDEPOP1.C -- DDE Server for Population Data
                (c) Charles Petzold, 1996
  ---------------------------------------------*/
 
#include <windows.h>
#include <dde.h>
#include <string.h>
#include "ddepop.h"
 
#include<stdio.h>
 
typedef struct
{
    unsigned int fAdvise : 1;
    unsigned int fDeferUpd : 1;
    unsigned int fAckReq : 1;
    unsigned int dummy : 13;
    long         lPopPrev;
}
POPADVISE;
 
#define ID_TIMER    1
#define DDE_TIMEOUT 3000
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ServerProc(HWND, UINT, WPARAM, LPARAM);
BOOL    CALLBACK TimerEnumProc(HWND, LONG);
BOOL    CALLBACK CloseEnumProc(HWND, LONG);
BOOL             PostDataMessage(HWND, HWND, int, BOOL, BOOL, BOOL);
 
char      szAppName[] = "DdePop1";
char      szServerClass[] = "DdePop1.Server";
HINSTANCE hInst;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    HWND        hwnd;
    MSG         msg;
    WNDCLASSEXA  wndclass;
 
    hInst = hInstance;
 
    // Register window class
 
    wndclass.cbSize = sizeof(wndclass);
    wndclass.style = 0;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIconA(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    wndclass.hIconSm = LoadIconA(hInstance, szAppName);
 
    RegisterClassExA(&wndclass);
 
    // Register window class for DDE Server
 
    wndclass.cbSize = sizeof(wndclass);
    wndclass.style = 0;
    wndclass.lpfnWndProc = ServerProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 2 * sizeof(DWORD);
    wndclass.hInstance = hInstance;
    wndclass.hIcon = NULL;
    wndclass.hCursor = NULL;
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szServerClass;
    wndclass.hIconSm = NULL;
 
    RegisterClassExA(&wndclass);
 
    hwnd = CreateWindowA(szAppName, "DDE Population Server",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);
 
    InitPops();                      // initialize 'pop' structure
 
    SetTimer(hwnd, ID_TIMER, 5000, NULL);
 
    ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
    UpdateWindow(hwnd);
 
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    KillTimer(hwnd, ID_TIMER);
 
    return msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static char szTopic[] = "US_Population";
    ATOM        aApp, aTop;
    HWND        hwndClient, hwndServer;
 
    switch (iMsg)
    {
    case WM_DDE_INITIATE:
 
        // wParam          -- sending window handle
        // LOWORD (lParam) -- application atom
        // HIWORD (lParam) -- topic atom
 
        hwndClient = (HWND)wParam;
 
        aApp = GlobalAddAtomA(szAppName);
        aTop = GlobalAddAtomA(szTopic);
 
        // Check for matching atoms, create window, and acknowledge
 
        if ((LOWORD(lParam) == NULL || LOWORD(lParam) == aApp) &&
            (HIWORD(lParam) == NULL || HIWORD(lParam) == aTop))
        {
            hwndServer = CreateWindowA(szServerClass, NULL,
                WS_CHILD, 0, 0, 0, 0,
                hwnd, NULL, hInst, NULL);
            if (!hwndServer)
            {
                MessageBox(hwnd, TEXT("Can't creating a window"),
                    TEXT("Error: DDEPOP1_A"), MB_OK);
                GlobalDeleteAtom(aApp);
                GlobalDeleteAtom(aTop);
                return 0;
            }
 
            SetWindowLongPtr(hwndServer, 0, (ULONG_PTR)hwndClient);
            SendMessage((HWND)wParam, WM_DDE_ACK,
                (WPARAM)hwndServer,
                MAKELPARAM(aApp, aTop));
        }
 
        // Otherwise, delete the atoms just created
 
        else
        {
            GlobalDeleteAtom(aApp);
            GlobalDeleteAtom(aTop);
        }
 
        return 0;
 
    case WM_TIMER:
    case WM_TIMECHANGE:
 
        // Calculate new current populations
 
        CalcPops();
 
        // Notify all child windows
 
        EnumChildWindows(hwnd, &TimerEnumProc, 0L);
        return 0;
 
    case WM_QUERYOPEN:
        return 0;
 
    case WM_CLOSE:
 
        // Notify all child windows
 
        EnumChildWindows(hwnd, &CloseEnumProc, 0L);
 
        break;                  // for default processing
 
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
 
LRESULT CALLBACK ServerProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    ATOM          aItem;
    char          szItem[10];
    DDEACK        DdeAck;
    DDEADVISE* pDdeAdvise;
    DWORD         dwTime;
    GLOBALHANDLE  hPopAdvise, hDdeAdvise, hCommands, hDdePoke;
    int           i;
    UINT          uiLow, uiHi;
    HWND          hwndClient;
    MSG           msg;
    POPADVISE* pPopAdvise;
    WORD          cfFormat, wStatus;
 
    switch (iMsg)
    {
    case WM_CREATE:
 
        // Allocate memory for POPADVISE structures
 
        hPopAdvise = GlobalAlloc(GHND, NUM_STATES * sizeof(POPADVISE));
 
        if (hPopAdvise == NULL)
            DestroyWindow(hwnd);
        else
            SetWindowLongPtr(hwnd, sizeof(DWORD), (ULONG_PTR)hPopAdvise);
 
        return 0;
 
    case WM_DDE_REQUEST:
 
        // wParam          -- sending window handle
        // LOWORD (lParam) -- data format
        // HIWORD (lParam) -- item atom
 
        hwndClient = (HWND)wParam;
        cfFormat = LOWORD(lParam);
        aItem = HIWORD(lParam);
 
        // Check for matching format and data item
 
        if (cfFormat == CF_TEXT)
        {
            GlobalGetAtomNameA(aItem, szItem, sizeof(szItem));
 
            for (i = 0; i < NUM_STATES; i++)
                if (strcmp(szItem, pop[i].szState) == 0)
                    break;
 
            if (i < NUM_STATES)
            {
                GlobalDeleteAtom(aItem);
                PostDataMessage(hwnd, hwndClient, i,
                    FALSE, FALSE, TRUE);
                return 0;
            }
        }
 
        // Negative acknowledge if no match
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            GlobalDeleteAtom(aItem);
        }
 
        return 0;
 
    case WM_DDE_ADVISE:
    {
        // wParam -- sending window handle
        // lParam -- DDEADVISE memory handle & item atom
 
        UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLow, &uiHi);
        FreeDDElParam(WM_DDE_ADVISE, lParam);
 
        hwndClient = (HWND)wParam;
        hDdeAdvise = (GLOBALHANDLE)uiLow;
        aItem = (ATOM)uiHi;
 
        pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
 
        // Check for matching format and data item
 
        if (pDdeAdvise->cfFormat == CF_TEXT)
        {
            GlobalGetAtomNameA(aItem, szItem, sizeof(szItem));
 
            for (i = 0; i < NUM_STATES; i++)
                if (strcmp(szItem, pop[i].szState) == 0)
                    break;
 
            // Fill in the POPADVISE structure and acknowledge
 
            if (i < NUM_STATES)
            {
                hPopAdvise = (GLOBALHANDLE)GetWindowLongPtr(hwnd, sizeof(DWORD));
                pPopAdvise = (POPADVISE*)
                    GlobalLock(hPopAdvise);
 
                pPopAdvise[i].fAdvise = TRUE;
                pPopAdvise[i].fDeferUpd = pDdeAdvise->fDeferUpd;
                pPopAdvise[i].fAckReq = pDdeAdvise->fAckReq;
                pPopAdvise[i].lPopPrev = pop[i].lPop;
 
                GlobalUnlock(hDdeAdvise);
                GlobalFree(hDdeAdvise);
 
                DdeAck.bAppReturnCode = 0;
                DdeAck.reserved = 0;
                DdeAck.fBusy = FALSE;
                DdeAck.fAck = TRUE;
 
                wStatus = *((WORD*)&DdeAck);
 
                if (!PostMessage(hwndClient, WM_DDE_ACK,
                    (WPARAM)hwnd,
                    PackDDElParam(WM_DDE_ACK,
                        wStatus, aItem)))
                {
                    GlobalDeleteAtom(aItem);
                }
                else
                {
                    PostDataMessage(hwnd, hwndClient, i,
                        pPopAdvise[i].fDeferUpd,
                        pPopAdvise[i].fAckReq,
                        FALSE);
                }
 
                GlobalUnlock(hPopAdvise);
                return 0;
            }
            else
            {
                MessageBox(hwnd, TEXT("WM_DDE_ASVISE (i >= NUM_STATES)"),
                    TEXT("ERROR: DDEPOP1_A.exe"),
                    MB_OK | MB_ICONSTOP);
            }
        }
        else
        {
            MessageBox(hwnd, 
                TEXT("WM_DDE_ASVISE (pPopAdvise.cfFormat != CF_TEXT)"),
                TEXT("ERROR: DDEPOP1_A.exe"),
                MB_OK | MB_ICONSTOP);
        }
 
        // Otherwise, post a negative WM_DDE_ACK
 
        GlobalUnlock(hDdeAdvise);
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            GlobalFree(hDdeAdvise);
            GlobalDeleteAtom(aItem);
            FreeDDElParam(WM_DDE_ACK, lParam);
        }
 
        return 0;
    }
    case WM_DDE_UNADVISE:
 
        // wParam          -- sending window handle
        // LOWORD (lParam) -- data format
        // HIWORD (lParam) -- item atom
 
        hwndClient = (HWND)wParam;
        cfFormat = LOWORD(lParam);
        aItem = HIWORD(lParam);
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = TRUE;
 
        hPopAdvise = (GLOBALHANDLE)GetWindowLongPtr(hwnd, sizeof(DWORD));
        pPopAdvise = (POPADVISE*)GlobalLock(hPopAdvise);
 
        // Check for matching format and data item
 
        if (cfFormat == CF_TEXT || cfFormat == NULL)
        {
            if (aItem == (ATOM)NULL)
                for (i = 0; i < NUM_STATES; i++)
                    pPopAdvise[i].fAdvise = FALSE;
            else
            {
                GlobalGetAtomNameA(aItem, szItem, sizeof(szItem));
 
                for (i = 0; i < NUM_STATES; i++)
                    if (strcmp(szItem, pop[i].szState) == 0)
                        break;
 
                if (i < NUM_STATES)
                    pPopAdvise[i].fAdvise = FALSE;
                else
                    DdeAck.fAck = FALSE;
            }
        }
        else
            DdeAck.fAck = FALSE;
 
        // Acknowledge either positively or negatively
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            if (aItem != (ATOM)NULL)
                GlobalDeleteAtom(aItem);
        }
 
        GlobalUnlock(hPopAdvise);
        return 0;
 
    case WM_DDE_EXECUTE:
 
        // Post negative acknowledge
 
        hwndClient = (HWND)wParam;
        hCommands = (GLOBALHANDLE)lParam;
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK,
                wStatus, (UINT)hCommands)))
        {
            GlobalFree(hCommands);
        }
        return 0;
 
    case WM_DDE_POKE:
 
        // Post negative acknowledge
 
        UnpackDDElParam(WM_DDE_POKE, lParam, &uiLow, &uiHi);
        FreeDDElParam(WM_DDE_POKE, lParam);
        hwndClient = (HWND)wParam;
        hDdePoke = (GLOBALHANDLE)uiLow;
        aItem = (ATOM)uiHi;
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        wStatus = *((WORD*)&DdeAck);
 
        if (!PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwnd,
            PackDDElParam(WM_DDE_ACK, wStatus, aItem)))
        {
            GlobalFree(hDdePoke);
            GlobalDeleteAtom(aItem);
        }
 
        return 0;
 
    case WM_DDE_TERMINATE:
 
        // Respond with another WM_DDE_TERMINATE iMsg
 
        hwndClient = (HWND)wParam;
        PostMessage(hwndClient, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
        DestroyWindow(hwnd);
        return 0;
 
    case WM_TIMER:
 
        // Post WM_DDE_DATA iMsgs for changed populations
 
        hwndClient = (HWND)GetWindowLongPtr(hwnd, 0);
        hPopAdvise = (GLOBALHANDLE)GetWindowLongPtr(hwnd, sizeof(DWORD));
        pPopAdvise = (POPADVISE*)GlobalLock(hPopAdvise);
 
        for (i = 0; i < NUM_STATES; i++)
        {
            if (pPopAdvise[i].fAdvise)
                if (pPopAdvise[i].lPopPrev != pop[i].lPop)
                {
                    if (!PostDataMessage(hwnd, hwndClient, i,
                        pPopAdvise[i].fDeferUpd,
                        pPopAdvise[i].fAckReq,
                        FALSE))
                        break;
 
                    pPopAdvise[i].lPopPrev = pop[i].lPop;
                }
        }
        GlobalUnlock(hPopAdvise);
        return 0;
 
    case WM_CLOSE:
 
        // Post a WM_DDE_TERMINATE iMsg to the client
 
        hwndClient = (HWND)GetWindowLongPtr(hwnd, 0);
        PostMessage(hwndClient, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
            if (PeekMessage(&msg, hwnd, WM_DDE_TERMINATE,
                WM_DDE_TERMINATE, PM_REMOVE))
                break;
 
        DestroyWindow(hwnd);
        return 0;
 
    case WM_DESTROY:
        hPopAdvise = (GLOBALHANDLE)GetWindowLongPtr(hwnd, sizeof(DWORD));
        GlobalFree(hPopAdvise);
        return 0;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
 
BOOL CALLBACK TimerEnumProc(HWND hwnd, LPARAM lParam)
{
    SendMessage(hwnd, WM_TIMER, 0, 0L);
 
    return TRUE;
}
 
BOOL CALLBACK CloseEnumProc(HWND hwnd, LPARAM lParam)
{
    SendMessage(hwnd, WM_CLOSE, 0, 0L);
 
    return TRUE;
}
 
BOOL PostDataMessage(HWND hwndServer, HWND hwndClient, int iState,
    BOOL fDeferUpd, BOOL fAckReq, BOOL fResponse)
{
    ATOM         aItem;
    char         szPopulation[16];
    DDEACK       DdeAck;
    DDEDATA* pDdeData;
    DWORD        dwTime;
    GLOBALHANDLE hDdeData;
    MSG          msg;
    WORD         wStatus;
 
    aItem = GlobalAddAtomA(pop[iState].szState);
 
    // Allocate a DDEDATA structure if not deferred update
 
    if (fDeferUpd)
    {
        hDdeData = NULL;
    }
    else
    {
        wsprintfA(szPopulation, "%ld\r\n", pop[iState].lPop);
 
        hDdeData = GlobalAlloc(GHND | GMEM_DDESHARE,
            sizeof(DDEDATA) + strlen(szPopulation));
 
        pDdeData = (DDEDATA*)GlobalLock(hDdeData);
 
        pDdeData->fResponse = fResponse;
        pDdeData->fRelease = TRUE;
        pDdeData->fAckReq = fAckReq;
        pDdeData->cfFormat = CF_TEXT;
 
        lstrcpyA((PSTR)pDdeData->Value, szPopulation);
 
        GlobalUnlock(hDdeData);
    }
 
    // Post the WM_DDE_DATA iMsg
 
    if (!PostMessage(hwndClient, WM_DDE_DATA, (WPARAM)hwndServer,
        PackDDElParam(WM_DDE_DATA, (UINT)hDdeData, aItem)))
    {
        if (hDdeData != NULL)
            GlobalFree(hDdeData);
 
        GlobalDeleteAtom(aItem);
        return FALSE;
    }
 
    // Wait for the acknowledge iMsg if it's requested
 
    if (fAckReq)
    {
        DdeAck.fAck = FALSE;
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
        {
            if (PeekMessage(&msg, hwndServer, WM_DDE_ACK, WM_DDE_ACK,
                PM_REMOVE))
            {
                UINT uiLow, uiHi;
                UnpackDDElParam(WM_DDE_ACK, msg.lParam, &uiLow, &uiHi);
                FreeDDElParam(WM_DDE_ACK, msg.lParam);
 
                wStatus = uiLow;
                DdeAck = *((DDEACK*)&wStatus);
                //aItem = HIWORD(msg.lParam);
                GlobalDeleteAtom((ATOM)uiHi);
                break;
            }
        }
 
        if (DdeAck.fAck == FALSE)
        {
            if (hDdeData != NULL)
                GlobalFree(hDdeData);
 
            //GlobalDeleteAtom(aItem);
            return FALSE;
        }
    }
 
    return TRUE;
}


DDEPOP1.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
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
/*---------------------------------------------------------------
   DDEPOP.H header file
 
   Data from "The World Almanac and Book of Facts 1992," page 75
  ---------------------------------------------------------------*/
 
#include <time.h>
 
struct
     {
     const char       *szState ;
     long        lPop70 ;
     long        lPop80 ;
     long        lPop90 ;
     long        lPop ;
     long        lPopLast ;
     long double a ;
     long double b ;
     long double c ;
     }
     pop[] = {
             "AL",   3444354,   3894025,   4040587, 0, 0, 0.0, 0.0, 0.0,
             "AK",    302583,    401851,    550043, 0, 0, 0.0, 0.0, 0.0,
             "AZ",   1775399,   2716546,   3665228, 0, 0, 0.0, 0.0, 0.0,
             "AR",   1923322,   2286357,   2350725, 0, 0, 0.0, 0.0, 0.0,
             "CA",  19971069,  23667764,  29760021, 0, 0, 0.0, 0.0, 0.0,
             "CO",   2209596,   2889735,   3294394, 0, 0, 0.0, 0.0, 0.0,
             "CT",   3032217,   3107564,   3287116, 0, 0, 0.0, 0.0, 0.0,
             "DE",    548104,    594338,    666168, 0, 0, 0.0, 0.0, 0.0,
             "DC",    756668,    638432,    606900, 0, 0, 0.0, 0.0, 0.0,
             "FL",   6791418,   9746961,  12937926, 0, 0, 0.0, 0.0, 0.0,
             "GA",   4587930,   5462982,   6478216, 0, 0, 0.0, 0.0, 0.0,
             "HI",    769913,    964691,   1108229, 0, 0, 0.0, 0.0, 0.0,
             "ID",    713015,    944127,   1006749, 0, 0, 0.0, 0.0, 0.0,
             "IL",  11110285,  11427409,  11430602, 0, 0, 0.0, 0.0, 0.0,
             "IN",   5195392,   5490214,   5544159, 0, 0, 0.0, 0.0, 0.0,
             "IA",   2825368,   2913808,   2776755, 0, 0, 0.0, 0.0, 0.0,
             "KS",   2249071,   2364236,   2477574, 0, 0, 0.0, 0.0, 0.0,
             "KY",   3220711,   3660324,   3685296, 0, 0, 0.0, 0.0, 0.0,
             "LA",   3644637,   4206116,   4219973, 0, 0, 0.0, 0.0, 0.0,
             "ME",    993722,   1125043,   1227928, 0, 0, 0.0, 0.0, 0.0,
             "MD",   3923897,   4216933,   4781468, 0, 0, 0.0, 0.0, 0.0,
             "MA",   5689170,   5737093,   6016425, 0, 0, 0.0, 0.0, 0.0,
             "MI",   8881826,   9262044,   9295297, 0, 0, 0.0, 0.0, 0.0,
             "MN",   3806103,   4075970,   4375099, 0, 0, 0.0, 0.0, 0.0,
             "MS",   2216994,   2520770,   2573216, 0, 0, 0.0, 0.0, 0.0,
             "MO",   4677623,   4916766,   5117073, 0, 0, 0.0, 0.0, 0.0,
             "MT",    694409,    786690,    799065, 0, 0, 0.0, 0.0, 0.0,
             "NE",   1485333,   1569825,   1578385, 0, 0, 0.0, 0.0, 0.0,
             "NV",    488738,    800508,   1201833, 0, 0, 0.0, 0.0, 0.0,
             "NH",    737681,    920610,   1109252, 0, 0, 0.0, 0.0, 0.0,
             "NJ",   7171112,   7365011,   7730188, 0, 0, 0.0, 0.0, 0.0,
             "NM",   1017055,   1303302,   1515069, 0, 0, 0.0, 0.0, 0.0,
             "NY",  18241391,  17558165,  17990455, 0, 0, 0.0, 0.0, 0.0,
             "NC",   5084411,   5880095,   6628637, 0, 0, 0.0, 0.0, 0.0,
             "ND",    617792,    652717,    638800, 0, 0, 0.0, 0.0, 0.0,
             "OH",  10657423,  10797603,  10847115, 0, 0, 0.0, 0.0, 0.0,
             "OK",   2559463,   3025487,   3145585, 0, 0, 0.0, 0.0, 0.0,
             "OR",   2091533,   2633156,   2842321, 0, 0, 0.0, 0.0, 0.0,
             "PA",  11800766,  11864720,  11881643, 0, 0, 0.0, 0.0, 0.0,
             "RI",    949723,    947154,   1003464, 0, 0, 0.0, 0.0, 0.0,
             "SC",   2590713,   3120729,   3486703, 0, 0, 0.0, 0.0, 0.0,
             "SD",    666257,    690768,    696004, 0, 0, 0.0, 0.0, 0.0,
             "TN",   3926018,   4591023,   4877185, 0, 0, 0.0, 0.0, 0.0,
             "TX",  11198655,  14225513,  16986510, 0, 0, 0.0, 0.0, 0.0,
             "UT",   1059273,   1461037,   1722850, 0, 0, 0.0, 0.0, 0.0,
             "VT",    444732,    511456,    562758, 0, 0, 0.0, 0.0, 0.0,
             "VA",   4651448,   5346797,   6187358, 0, 0, 0.0, 0.0, 0.0,
             "WA",   3413244,   4132353,   4866692, 0, 0, 0.0, 0.0, 0.0,
             "WV",   1744237,   1950186,   1793477, 0, 0, 0.0, 0.0, 0.0,
             "WI",   4417821,   4705642,   4891769, 0, 0, 0.0, 0.0, 0.0,
             "WY",    332416,    469557,    453588, 0, 0, 0.0, 0.0, 0.0,
             "US", 203302031, 226542203, 248709873, 0, 0, 0.0, 0.0, 0.0
             } ;
 
#define NUM_STATES (sizeof (pop) / sizeof (pop[0]))
 
void CalcPops (void)
     {
     int    i ;
     time_t lTime ;
 
     time (&lTime) ;                    // time in seconds since 1/1/70
     lTime -= 92L * 24 * 60 * 60 ;      // time in seconds since 4/1/70
 
     for (i = 0 ; i < NUM_STATES ; i++)
          pop[i].lPop = (long) (pop[i].a * lTime * lTime +
                                pop[i].b * lTime +
                                pop[i].c) ;
     }
 
void InitPops (void)
     {
     int         i ;
     long double ldSec80, ldSec90 ;
 
     ldSec80 = 3653.0 * 24 * 60 * 60 ;  // seconds from 4/1/70 to 4/1/80
     ldSec90 = 7305.0 * 24 * 60 * 60 ;  // seconds from 4/1/70 to 4/1/90
 
     for (i = 0 ; i < NUM_STATES ; i++)
          {
          pop[i].a = (ldSec90 * (pop[i].lPop80 - pop[i].lPop70) +
                      ldSec80 * (pop[i].lPop70 - pop[i].lPop90)) /
                     (ldSec90 * ldSec80 * (ldSec80 - ldSec90)) ;
 
          pop[i].b = (ldSec90 * ldSec90 * (pop[i].lPop70 - pop[i].lPop80) +
                      ldSec80 * ldSec80 * (pop[i].lPop90 - pop[i].lPop70)) /
                     (ldSec90 * ldSec80 * (ldSec80 - ldSec90)) ;
 
          pop[i].c = pop[i].lPop70 ;
          }
 
     CalcPops () ;
     }


DDEPOP1.RC
C++
1
2
3
4
5
/*----------------------------
   DDEPOP1.RC resource script
  ----------------------------*/
 
DdePop1 ICON ddepop.ico
1
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
14.11.2023, 14:03  [ТС]
SHOWPOP1.C
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
/*-----------------------------------------
   SHOWPOP1.C -- DDE Client using DDEPOP1
                 (c) Charles Petzold, 1996
  -----------------------------------------*/
 
#include <windows.h>
#include <dde.h>
#include <stdlib.h>
#include <string.h>
#include "showpop.h"
 
#define WM_USER_INITIATE (WM_USER + 1)
#define DDE_TIMEOUT      3000
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
char szAppName[] = "ShowPop1";
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    HWND       hwnd;
    MSG        msg;
    WNDCLASSEXA wndclass;
 
    wndclass.cbSize = sizeof(wndclass);
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIconA(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    wndclass.hIconSm = LoadIconA(hInstance, szAppName);
 
    RegisterClassExA(&wndclass);
 
    hwnd = CreateWindowA(szAppName, "DDE Client - US Population",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);
 
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
 
    SendMessage(hwnd, WM_USER_INITIATE, 0, 0L);
 
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static BOOL   fDoingInitiate = TRUE;
    static char   szServerApp[] = "DdePop1",
        szTopic[] = "US_Population";
    static HWND   hwndServer = NULL;
    static long   cxChar, cyChar;
    ATOM          aApp, aTop, aItem;
    char          szBuffer[24], szPopulation[16], szItem[16];
    DDEACK        DdeAck;
    DDEDATA* pDdeData;
    DDEADVISE* pDdeAdvise;
    DWORD         dwTime;
    GLOBALHANDLE  hDdeAdvise, hDdeData;
    HDC           hdc;
    MSG           msg;
    PAINTSTRUCT   ps;
    int           i;
    long          x, y;
    TEXTMETRIC    tm;
    WORD          wStatus;
    UINT          uiLow, uiHi;
 
    switch (iMsg)
    {
    case WM_CREATE:
        hdc = GetDC(hwnd);
        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cyChar = tm.tmHeight + tm.tmExternalLeading;
        ReleaseDC(hwnd, hdc);
        return 0;
 
    case WM_USER_INITIATE:
 
        // Broadcast WM_DDE_INITIATE iMsg
 
        aApp = GlobalAddAtomA(szServerApp);
        aTop = GlobalAddAtomA(szTopic);
 
        SendMessage(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwnd,
            MAKELONG(aApp, aTop));
 
        // If no response, try loading DDEPOP first
 
        if (hwndServer == NULL)
        {
            //WinExec(szServerApp, SW_SHOWMINNOACTIVE);
            SHELLEXECUTEINFOA shinf;
            shinf.cbSize = sizeof(SHELLEXECUTEINFO);
            shinf.fMask = NULL;
            shinf.hwnd = NULL;
            shinf.lpVerb = NULL;
            shinf.lpFile = szServerApp;
            shinf.lpParameters = NULL;
            shinf.lpDirectory = NULL;
            shinf.nShow = SW_SHOWMINNOACTIVE;
            shinf.hInstApp = NULL;
 
            ShellExecuteExA(&shinf);
 
            SendMessage(HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwnd,
                MAKELONG(aApp, aTop));
        }
 
        // Delete the atoms
 
        GlobalDeleteAtom(aApp);
        GlobalDeleteAtom(aTop);
        fDoingInitiate = FALSE;
 
        // If still no response, display message box
 
        if (hwndServer == NULL)
        {
            MessageBoxA(hwnd, "Cannot connect with DDEPOP1.EXE!",
                szAppName, MB_ICONEXCLAMATION | MB_OK);
 
            return 0;
        }
 
        // Post WM_DDE_ADVISE iMsgs
 
        for (i = 0; i < NUM_STATES; i++)
        {
            hDdeAdvise = GlobalAlloc(GHND,
                sizeof(DDEADVISE));
 
            if (!hDdeAdvise)
            {
                MessageBox(hwnd, TEXT("GlobalAlloc failure"),
                    TEXT("ERROR: WM_USER_INITIATE"),
                    MB_OK);
                break;
            }
 
            pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
            if (!pDdeAdvise)
            {
                MessageBox(hwnd, TEXT("GlobalLock failure"),
                    TEXT("ERROR: WM_USER_INITIATE"),
                    MB_OK);
                break;
            }
            pDdeAdvise->reserved = 0;
            pDdeAdvise->fAckReq = TRUE;
            //pDdeAdvise->fAckReq = FALSE;
            pDdeAdvise->fDeferUpd = FALSE;
            pDdeAdvise->cfFormat = CF_TEXT;
 
            GlobalUnlock(hDdeAdvise);
 
            aItem = GlobalAddAtomA(pop[i].szAbb);
 
            if (!PostMessage(hwndServer, WM_DDE_ADVISE, (WPARAM)hwnd,
                PackDDElParam(WM_DDE_ADVISE,
                    (UINT_PTR)hDdeAdvise, aItem)))
            {
                GlobalFree(hDdeAdvise);
                GlobalDeleteAtom(aItem);
                FreeDDElParam(WM_DDE_ADVISE, lParam);
                break;
            }
 
            DdeAck.fAck = FALSE;
 
            dwTime = GetCurrentTime();
 
            while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
            {
                if (PeekMessage(&msg, hwnd, WM_DDE_ACK,
                    WM_DDE_ACK, PM_REMOVE))
                {
                    UnpackDDElParam(WM_DDE_ACK, msg.lParam, &uiLow, &uiHi);
                    FreeDDElParam(WM_DDE_ACK, msg.lParam);
 
                    GlobalDeleteAtom((ATOM)uiHi);
 
                    wStatus = uiLow;
                    DdeAck = *((DDEACK*)&wStatus);
 
                    if (DdeAck.fAck == FALSE)
                        GlobalFree(hDdeAdvise);
 
                    break;
                }
            }
 
            if (DdeAck.fAck == FALSE)
                break;
 
            while (PeekMessage(&msg, hwnd, WM_DDE_FIRST,
                WM_DDE_LAST, PM_REMOVE))
            {
                DispatchMessage(&msg);
            }
        }
 
        if (i < NUM_STATES)
        {
            MessageBoxA(hwnd, "Failure on WM_DDE_ADVISE!",
                szAppName, MB_ICONEXCLAMATION | MB_OK);
        }
        return 0;
 
    case WM_DDE_ACK:
 
        // In response to WM_DDE_INITIATE, save server window
 
        if (fDoingInitiate)
        {
            //UnpackDDElParam(WM_DDE_ACK, lParam, &uiLow, &uiHi);
            //FreeDDElParam(WM_DDE_ACK, lParam);
            uiLow = LOWORD(lParam); 
            uiHi  = HIWORD(lParam);
            hwndServer = (HWND)wParam;
            GlobalDeleteAtom((ATOM)uiLow);
            GlobalDeleteAtom((ATOM)uiHi);
        }
        return 0;
 
    case WM_DDE_DATA:
 
        // wParam -- sending window handle
        // lParam -- DDEDATA memory handle & item atom
 
        UnpackDDElParam(WM_DDE_DATA, lParam, &uiLow, &uiHi);
        FreeDDElParam(WM_DDE_DATA, lParam);
 
        hDdeData = (GLOBALHANDLE)uiLow;
        pDdeData = (DDEDATA*)GlobalLock(hDdeData);
        aItem = (ATOM)uiHi;
 
        // Initialize DdeAck structure
 
        DdeAck.bAppReturnCode = 0;
        DdeAck.reserved = 0;
        DdeAck.fBusy = FALSE;
        DdeAck.fAck = FALSE;
 
        // Check for matching format and data item
 
        if (pDdeData->cfFormat == CF_TEXT)
        {
            GlobalGetAtomNameA(aItem, szItem, sizeof(szItem));
 
            for (i = 0; i < NUM_STATES; i++)
                if (strcmp(szItem, pop[i].szAbb) == 0)
                    break;
 
            if (i < NUM_STATES)
            {
                strcpy_s(szPopulation, 16, (char*)pDdeData->Value);
                pop[i].lPop = atol(szPopulation);
                InvalidateRect(hwnd, NULL, FALSE);
 
                DdeAck.fAck = TRUE;
            }
        }
 
        // Acknowledge if necessary
 
        if (pDdeData->fAckReq == TRUE)
        {
            wStatus = *((WORD*)&DdeAck);
 
            if (!PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hwnd,
                PackDDElParam(WM_DDE_ACK,
                    wStatus, aItem)))
            {
                GlobalDeleteAtom(aItem);
                GlobalUnlock(hDdeData);
                GlobalFree(hDdeData);
                return 0;
            }
        }
        else
        {
            GlobalDeleteAtom(aItem);
        }
 
        // Clean up
 
        if (pDdeData->fRelease == TRUE || DdeAck.fAck == FALSE)
        {
            GlobalUnlock(hDdeData);
            GlobalFree(hDdeData);
        }
        else
        {
            GlobalUnlock(hDdeData);
        }
 
        return 0;
 
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
 
        for (i = 0; i < NUM_STATES; i++)
        {
            if (i < (NUM_STATES + 1) / 2)
            {
                x = cxChar;
                y = i * cyChar;
            }
            else
            {
                x = 44 * cxChar;
                y = (i - (NUM_STATES + 1) / 2) * cyChar;
            }
 
            TextOutA(hdc, x, y, szBuffer,
                wsprintfA(szBuffer, "%-20s",
                    (PSTR)pop[i].szState));
 
            x += 36 * cxChar;
 
            SetTextAlign(hdc, TA_RIGHT | TA_TOP);
 
            TextOutA(hdc, x, y, szBuffer,
                wsprintfA(szBuffer, "%10ld", pop[i].lPop));
 
            SetTextAlign(hdc, TA_LEFT | TA_TOP);
        }
 
        EndPaint(hwnd, &ps);
        return 0;
 
    case WM_DDE_TERMINATE:
 
        // Respond with another WM_DDE_TERMINATE iMsg
 
        PostMessage(hwndServer, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
        hwndServer = NULL;
        return 0;
 
    case WM_CLOSE:
        if (hwndServer == NULL)
            break;
 
        // Post WM_DDE_UNADVISE iMsg
 
        PostMessage(hwndServer, WM_DDE_UNADVISE, (WPARAM)hwnd,
            MAKELONG(CF_TEXT, NULL));
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
        {
            if (PeekMessage(&msg, hwnd, WM_DDE_ACK,
                WM_DDE_ACK, PM_REMOVE))
                break;
        }
 
        // Post WM_DDE_TERMINATE iMsg
 
        PostMessage(hwndServer, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
 
        dwTime = GetCurrentTime();
 
        while (GetCurrentTime() - dwTime < DDE_TIMEOUT)
        {
            if (PeekMessage(&msg, hwnd, WM_DDE_TERMINATE,
                WM_DDE_TERMINATE, PM_REMOVE))
                break;
        }
 
        break;             // for default processing
 
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}


SHOWPOP1.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
30
31
32
33
34
35
36
37
38
39
40
/*-----------------------
   SHOWPOP.H header file
  -----------------------*/
 
struct
     {
     const char *szAbb ;
     const char *szState ;
     long  lPop ;
     }
     pop[] = {
             "AL", "Alabama",             0, "AK", "Alaska",              0,
             "AZ", "Arizona",             0, "AR", "Arkansas",            0,
             "CA", "California",          0, "CO", "Colorado",            0,
             "CT", "Connecticut",         0, "DE", "Delaware",            0,
             "DC", "Dist. of Columbia",   0, "FL", "Florida",             0,
             "GA", "Georgia",             0, "HI", "Hawaii",              0,
             "ID", "Idaho",               0, "IL", "Illinois",            0,
             "IN", "Indiana",             0, "IA", "Iowa",                0,
             "KS", "Kansas",              0, "KY", "Kentucky",            0,
             "LA", "Louisiana",           0, "ME", "Maine",               0,
             "MD", "Maryland",            0, "MA", "Massachusetts",       0,
             "MI", "Michigan",            0, "MN", "Minnesota",           0,
             "MS", "Mississippi",         0, "MO", "Missouri",            0,
             "MT", "Montana",             0, "NE", "Nebraska",            0,
             "NV", "Nevada",              0, "NH", "New Hampshire",       0,
             "NJ", "New Jersey",          0, "NM", "New Mexico",          0,
             "NY", "New York",            0, "NC", "North Carolina",      0,
             "ND", "North Dakota",        0, "OH", "Ohio",                0,
             "OK", "Oklahoma",            0, "OR", "Oregon",              0,
             "PA", "Pennsylvania",        0, "RI", "Rhode Island",        0,
             "SC", "South Carolina",      0, "SD", "South Dakota",        0,
             "TN", "Tennessee",           0, "TX", "Texas",               0,
             "UT", "Utah",                0, "VT", "Vermont",             0,
             "VA", "Virginia",            0, "WA", "Washington",          0,
             "WV", "West Virginia",       0, "WI", "Wisconsin",           0,
             "WY", "Wyoming",             0, "US", "United States Total", 0
             } ;
 
#define NUM_STATES (sizeof (pop) / sizeof (pop[0]))
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.11.2023, 14:03

Нужны примеры по Dynamic Data Display
Есть у кого-нибудь какие-нибудь примеры? Хотя бы какую-нибудь линию/фигуру вывести бы:)

Как нарисовать график в Dynamic Data Display
Помогите создать график sin в Dynamic Data Display на имено WPF приложении офф сайте имеются примеры, но нет исходного кода. В Silverlight...

не поддерживается тип контекста в Dynamic Data на VS2012
Добрый день! Кто нибудь пользовался Dynamic Data на VS2012? На 2010 работает без проблем, а в 2012 выдает ошибку &quot;Тип контекста...

Нужен дистрибутив Active Reports Data Dynamic
Нужен дистрибутив Active Reports Data Dynamic если можно, отправьте alm1@rbcmail.ru = спасибо

[WPF] Dynamic Data Display и Множество коллекций
Есть контролл D3 для отображения графиков. Есть ObservableDataSource&lt;Point&gt; tmp; tmp привязан к графику. т.е. при добавлении новых точек...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru