Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибки ddeml.h 
:(
    Опции темы
wallstreet
Дата 2.9.2011, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Пишу свой DDE Сервер.
Для этого добавляю головной файл ddeml.h в котором, при компиляции, находится 188 ошибок.
Причем ошибки начиная от синтаксических (не там точка с запятой) и до необъявленных идентфикаторов типа HSZ, HCONVLIST и тд.
Пишу в VS2008Pro.

Так вот вопрос, что я делаю не так и как эти ошибки устранить?
PM MAIL   Вверх
boostcoder
Дата 2.9.2011, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



ссылку на файл, пожалуйста. и процитируйте ошибки.
PM WWW   Вверх
wallstreet
Дата 2.9.2011, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Сылка на проект

файл с ошибками в прикрепленном файле

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  errors.txt 31,60 Kb
PM MAIL   Вверх
Estranged
Дата 2.9.2011, 20:17 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



В ddemlsr.cpp перед <windowsx.h> подключить <windows.h> и переставить местами <dde.h> и <ddeml.h> (т.е. dde.h должен быть перед ddeml.h)
В ddemlcl.cpp переставить местами <dde.h> и <ddeml.h>
PM MAIL   Вверх
wallstreet
Дата 5.9.2011, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



спасибо, разобрался с той проблемой и настигла новая. 
Суть в том, что в моем проекте 3 .срр файла, в одном серверная часть, в другом клиентская и в третьем файле мейн функция запускающая сервер и отправляющая\запрашивающая данные и выводящая в консоль. В общем, компилятор стал ругаться на то, что я многократно определил идентификаторы.
На самом деле я их все закомментил и все равно ругается.
Цитата

Ошибка    1    error LNK2005: "int (__stdcall* lpDdeProc)(void)" (?lpDdeProc@@3P6GHXZA) уже определен в ddemlcl.obj    ddemlsr.obj
Ошибка    2    error LNK2005: "unsigned long idInst" (?idInst@@3KA) уже определен в ddemlcl.obj    ddemlsr.obj
Ошибка    3    error LNK2005: "struct HSZ__ * hszService" (?hszService@@3PAUHSZ__@@A) уже определен в ddemlcl.obj    ddemlsr.obj
Ошибка    4    error LNK2005: "struct HSZ__ * hszTopic" (?hszTopic@@3PAUHSZ__@@A) уже определен в ddemlcl.obj    ddemlsr.obj
Ошибка    5    error LNK2005: "struct HSZ__ * hszItem" (?hszItem@@3PAUHSZ__@@A) уже определен в ddemlcl.obj    ddemlsr.obj
Ошибка    6    fatal error LNK1169: обнаружен многократно определенный символ - один или более    C:\Users\1\Documents\Visual Studio 2008\Projects\DDEServer\Debug\DDEServer.exe    1

Где ошибся?

Это сообщение отредактировал(а) GremlinProg - 7.9.2011, 06:08
PM MAIL   Вверх
Estranged
Дата 6.9.2011, 00:01 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



wallstreet, машина никогда не обманет. Если идентификаторы дублируются, то они дублируются в самом деле.

Вот гарантированно в ddemlsr.cpp есть 
Код

FARPROC lpDdeProc;
HSZ hszService = NULL;
HSZ hszTopic = NULL;
HSZ hszItem = NULL;

и в ddemlsr.cpp есть то же самое:
Код

FARPROC lpDdeProc;
HSZ hszService = NULL;
HSZ hszTopic = NULL;
HSZ hszItem = NULL;

Ищите лучше.

Цитата(wallstreet @  5.9.2011,  22:03 Найти цитируемый пост)
Суть в том, что в моем проекте 3 .срр файла, в одном серверная часть, в другом клиентская и в третьем файле мейн функция запускающая сервер и отправляющая\запрашивающая данные и выводящая в консоль.

Как все сложно. А в третьем файле main функция запускать должна сервер из первого файла, из второго файла - клиент?

В таком случае надо определиться:
эти переменные для сервера и клиента общие или у каждого они уникальны.

Для этого в С есть специальные ключевые слова, которые в данном случае указывают линкеру, где эта переменная находится: в текущей единице трансляции, где-то в другой единице трансляции. Т.н. спецификаторы класса памяти, коих всего 4, но в данном случае интересны два.
Под единицей трансляции понимается результат обработки препроцессором исходного файла.
Таким образом, для компилятора эти переменные в разных единицах трансляции не мешают. Когда дело доходит до линкера, он "видит", что один и тот же объект дважды объявлен в разных единицах трансляции. Что должен делать линкер? Объединить их в одну и выделить память под одну переменную и сделать отсылку на один и тот же участок памяти или разделить их по разным участкам памяти. Линкер этого "не знает".

И эти ключевые слова
static - данная (у нас переменные глобальные) переменная доступна только в текущей единице трансляции
extern - данная переменная находится где-то в другой единице трансляции, причем без указания где именно.

теперь надо решить вопрос: эти переменные для сервера и клиента общие или у каждого они уникальны?
Применить к ним extern или static.

например:

в ddemlsr.cpp
Код

FARPROC lpDdeProc;
HSZ hszService = NULL;
HSZ hszTopic = NULL;
HSZ hszItem = NULL;

в ddemlsr.cpp
Код

extern FARPROC lpDdeProc;// это вряд ли, у сервера и клиента разные функции обработки dde
extern HSZ hszService;
extern HSZ hszTopic;
extern HSZ hszItem;

или же
в ddemlsr.cpp
Код

static FARPROC lpDdeProc;
static HSZ hszService;
static HSZ hszTopic;
static HSZ hszItem;

в ddemlsr.cpp
Код

static FARPROC lpDdeProc;
static HSZ hszService;
static HSZ hszTopic;
static HSZ hszItem;


M
GremlinProg
для форматирования текста программного кода пользуйтесь тегами [сode][/сode]!


Это сообщение отредактировал(а) GremlinProg - 7.9.2011, 06:12
PM MAIL   Вверх
wallstreet
Дата 6.9.2011, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



ДДЕСервер

Вроде разобрался с предыдущей проблемой и вот сейчас похоже столкнулся с новой.
Нужно получить HINSTANSE моего консольного приложения и делать это гугл мне советует с помощью
GetModuleHandle(). 
Так вот в режиме дебаг заметил что эта функция не возвращает никакого значения.
В моем случае hInst = 00000000

Для большей наглядности залил проект.
Буду очень благодарен если направите в нужное русло.
В очередной раз)
PM MAIL   Вверх
Estranged
Дата 6.9.2011, 23:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Интересно, чем вы руководствовались, когда писали ЭТО:
Код

hInst = GetModuleHandle((LPCWSTR)"hInst");


Функция же принимает входной параметр: The name of the loaded module (either a .dll or .exe file)

hInst - это модуль такой есть?
Сомневаюсь все же.
Второе: (LPCWSTR)"hInst" это такая хитрость обойти ошибку C2664 компилятора? Не могу привести тип 'const char [6]' к 'LPCWSTR'?

Для этого специально заведена константа L. 
LPCWSTR - long ponter to const wide string. Потому что проект собирается с использованием UNICODE набора символов.
Для этого требуется строку привести к этому UNICODE:
L"hInst". Что само по себе плохо. Потому что если сменить набор символов на т.н. multi-byte character set, то программа перестанет компилироваться, т.к. L уже не нужна.
Для обхода этого ограничения придумали макрос:
TEXT (a) - http://msdn.microsoft.com/en-us/library/dd...v=vs.85%29.aspx
можно использовать _T(a)
например:
TEXT("hInst");

Поэтому следует написать:
GetModuleHandle (TEXT ("hInst"));

Но даже в этом случае функция вернет NULL. 

(Впрочем, непонятно, зачем понадобилась эта самая HINSTANSE  hInst, ведь она нигде не используется, это так, по-секрету. Если все же думаете, что MakeProcInstance для чего-то использует hInst, то это заблуждение. Теперь этот макрос устарел и не должен применяться. Это наследие Win16, в Win32 такое применять не нужно. См. http://msdn.microsoft.com/en-us/site/aa383722 )

А если очень надо, то получить ее можно вот так:
Код

hInst = GetModuleHandle (NULL);


Скажу по-секрету, что это на самом деле ни что иное, как виртуальный адрес, куда загружен исполняемый модуль процесса, который вызвал эту функцию с таким параметром. Даже если вызвал не главный поток в какой-либо dll а не в самом исполняемом модуле процесса.

Совершенно невозбранно можно поглядеть адрес загрузки любого модуля, например, ntdll.dll
Код

hInst = GetModuleHandle (TEXT ("ntdll.dll"));

PM MAIL   Вверх
wallstreet
Дата 7.9.2011, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Спасибо большое, с этим разобрался.

DDE Server

но не могу понять, почему не инициализируется идентификатор канала hConv?
что делаю не так?

Это сообщение отредактировал(а) wallstreet - 7.9.2011, 23:56
PM MAIL   Вверх
Estranged
Дата 8.9.2011, 00:17 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Да вроде бы должен инициализироваться.

Тут инициализироваться должен, а потом закрывается соединение.
Код

     // Инициализируем DDEML и создаем канал связи
     if(hConv == NULL)
      {
        hConv = DDEClientOpen(hInst,(LPSTR)"BMPServer",(LPSTR)"BMPFile",(LPSTR)"DDEData");


Где он должен инициализироваться, но не инициализируется?
PM MAIL   Вверх
wallstreet
Дата 8.9.2011, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



все правильно, просто перед этим сам сервер должен зарегистрировать сервис, топик и айтем в библиотеке DDEML, а при попытке это сделать :

Код

DDEServerOpen(hInst,(LPSTR)"BMPServer",(LPSTR)"BMPFile",(LPSTR)"DDEData");


ничего не происходит, т.е. не регистрируется сервис. Т.е. выполняется только клиентская часть, но создать канал не возможно, т.к. нет такого зарегистрированого сервера с аналогичным сервисом.

блин я в тупике((

Ссылка на проект

Это сообщение отредактировал(а) wallstreet - 8.9.2011, 20:30
PM MAIL   Вверх
Estranged
Дата 9.9.2011, 00:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Жаль, тут нет смайлика facepalm...

Сегодня мы познакомимся с кодировкой ASCII. Как известно, печатные символы машина должна как-то отображать на экране в виде, понятном человеку. 
И ASCII - кодировка для представления арабских цифр, латинского и национального алфавитов (для этого немного дорабатывается сама кодировка), а так же знаков препинания и управляющих символов. Что позволяет невозбранно печатать символы как на экране, так и на принтере времен прошлого века.
Образно говоря, это цифровое представление алфавита.

тип данных char - character предназначен для хранения строковых данных (если заведен массив) или символов. Этот тип данных хранит ASCII код.

Теперь возвращаемся к коду:
Код

    char ch;
    hInst = GetModuleHandle(NULL);
    cout << "Start the server? (1 - yes|| 2 - no): ";
    cin >> ch;
    switch(ch)
    {
    case 1:
        {
            DDEServerOpen(hInst, (LPSTR)"BMPServer", (LPSTR)"BMPFile", (LPSTR)"DDEData");
        }
    case 2:
        {
            // Завершаем работу с DDEML
            DDEServerClose();
        }
    }


Запрос ввести 1 или 2. Мы печатаем на клавиатуре '1' или '2'. Это печатный символ. Операционная система транслирует код нажатой клавиши в соответствующий код ASCII, и программе "кажется", что пользователь нажал '1' или '2'.
Код символа помещается по адресу ch где-то в стеке.

Обращаемся к таблице кодов и находим, что код символа '1' есть число 49, а код '2' - 50. Поэтому по адресу ch находится число 49 или 50.

Далее мы переходим к ветвлению, которое, кажется, все же неправильно написано.
сравнить 49 (50) с 1 или 2. Совпадений нет. Поэтому программа сразу же завершает свое выполнение.
Т.е. мы пытаемся сравнить код символа '1' с самим числом 1.

Что же делать?

Как говорят физики: переведите все в систему СИ, тонны перевести в килограммы и т.п.
Для этого можно вычесть из ch код символа 0, который равен 48 или же сравнивать ch с кодами символов '1' и '2':

Перевести код символа цифры в саму цифру:
Код

switch(ch - '0') // или же ch - 48, что делать вообще-то можно, но будут бить по рукам
case 1:
...
case 2:
...


или же сравнить код с кодом цифры
Код

switch(ch)
case '1':// одинарные кавычки
...
case '2':
...


И в-третьих:
после case потерян break?

Код

    switch(ch)
    {
    case '1':
        {
            ;
        }
        break;
    case '2':
        {
            ;
        }
        break;
    }


Потому что если выбрать 1, то выполнится ветка 1 и ветка 2, а судя по сообщению "Start the server? (1 - yes|| 2 - no): " такое не планировалось явно: создать сервер и тут же его закрыть. Хотя я могу ошибаться.
PM MAIL   Вверх
wallstreet
Дата 12.9.2011, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Спасибо за комплексные ответы.
Вы для меня, как, наверное и для всех участников этой ветки, бесценный кладязь информации.

С ошибками разобрался, все работает.
Единтственно, выводит информацию по серверу вместо:
PM MAIL   Вверх
wallstreet
Дата 12.9.2011, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Спасибо за комплексные ответы.
Вы для меня, как, наверное, и для всех участников этой ветки бесценный кладязь информации.

С ошибками разобрался, все работает.
Единтственно, выводит информацию по серверу вместо:

Цитата

"DDEML Server v.1.0, © Gursky A.K.";


так как показано на рисунке. Кстати если после А.К. поставить штук 50 пробелов, то вот эти ероглифы перестают закрывать остаток надписи.

user posted image


DDE server

Это сообщение отредактировал(а) wallstreet - 12.9.2011, 16:16
PM MAIL   Вверх
Estranged
Дата 12.9.2011, 22:47 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



В DDEReceive дописать:
Код

    // Получаем строку от сервера 
    if(hData != NULL)
    {
      DWORD dwGetBytes = DdeGetData(hData, (LPBYTE)szBuf, nBufSize, 0L);
      *(LPSTR)(((LPBYTE)szBuf) + dwGetBytes) = '\0';


В DdeServerCallback заменить третий параметр DdeCreateDataHandle:
Код

hData = DdeCreateDataHandle(idInst, (LPBYTE)szDDEServerVersion, sizeof (szDDEServerVersion), 0, hszItem, CF_TEXT, 0);

PM MAIL   Вверх
wallstreet
Дата 13.9.2011, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Спасибо за помощь, теперь все как надо.
Не понимаю почему появляются эти каракули, если при создании области памяти указывается размер буфера 

Цитата

sizeof(szDDEServerVersion)


кстати чем функция sizeof() более подходит чем lstrlen(), которая возвращает не кол-во символов в строке, а непосредственно длину без учета '\0'?
А еще по возможности прокомментируйте эту строку:
Цитата

*(LPSTR)(((LPBYTE)szBuf) + dwGetBytes) = '\0';

не понимаю как мы к массиву unsigned char прибавляем  unsigned long и присваиваем результату '\0'... Фактически замещая иероглифы?!?

Пользуясь случаем еще один вопрос хотел бы прояснить для себя. 
В чем разница между 0 и 0L, если говорим о типе DWORD?

Заранее благодарю!

Это сообщение отредактировал(а) wallstreet - 13.9.2011, 22:59
PM MAIL   Вверх
Estranged
Дата 14.9.2011, 01:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Цитата(wallstreet @  13.9.2011,  22:41 Найти цитируемый пост)
Не понимаю почему появляются эти каракули, если при создании области памяти указывается размер буфера

Каракули появляются из-за неправильного указания размера буфера. DdeCreateDataHandle требует размер буфера в байтах, lstrlen же в данном случае требует UNICODE строку, коей szDDEServerVersion не является, поэтому надо использовать lstrlenA, но нет смысла это делать, потому что строка szDDEServerVersion не изменяется нигде, отчего можно использовать sizeof, который будет вычислен в процессе компиляции, а не во время работы программы. Конечно, если длина строки заранее неизвестна, то надо использовать lstrlenA (строка) + 1, в данном случае просто совпадение, что длина строки равна ее размеру в байтах, для UNICODE такой финт не проходит, поэтому универсальный способ - умножить размер строки на размер одного символа строки ((lstrlen () + 1) * sizeof (TCHAR)), для UNICODE это будет равносильно умножению на два, а для однобайтовых символов - на 1.

Цитата(wallstreet @  13.9.2011,  22:41 Найти цитируемый пост)
А еще по возможности прокомментируйте эту строку

Эта строка записывает нуль-терминатор после последнего актуального символа, полученного в функции DdeGetData, эта строка не нужна здесь, если есть учет нуль-терминатора в DdeCreateDataHandle.
И не замещает иероглифы, а устанавливает окончание строки. Все строки оканчиваются специальным непечатным символом - нуль-терминатором. Вообще-то, это арифметика указателей, просто найти адрес по смещению dwGetBytes байт от начала szBuf и вписать туда нуль-терминатор.

Цитата(wallstreet @  13.9.2011,  22:41 Найти цитируемый пост)
В чем разница между 0 и 0L, если говорим о типе DWORD?

DWORD - double word. Word - 16-битное число. В данном случае, это 32-битное беззнаковое целое число (unsigned long).
А посфикс L в числе - это просто указание, что данная константа типа long. Формально в этом проекте разницы нет никакой, т.к. в модели данных (компилятор MSVS C/C++) размеры в байтах типа int и long совпадают, разница есть тогда, когда long больше по размеру, чем int, такое тоже бывает.

Это сообщение отредактировал(а) Estranged - 14.9.2011, 01:11
PM MAIL   Вверх
GremlinProg
Дата 14.9.2011, 05:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: нет
Всего: 106



ужос  smile 

M
GremlinProg
еще немного, и тема перекочует в C++ для начинающих



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 16.9.2011, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: нет
Всего: 106




M
GremlinProg
Тема перемещена из раздела C/C++: Системное программирование и WinAPI



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
wallstreet
Дата 22.9.2011, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Добрый день.
Решил сервер и клиент разбить на два разных приложения и не получается подсоединиться клиентом к серверу, хотя идентификаторы сервиса и топика у них одни и те же. Клиент подвисает на минуту, две и в результате не коннектится.
Чувствую, что в какой-то момент нужно приостановить работу сервера и каким-то образом ждать пока клиент не создаст коннект.Только как это сделать не могу понять. Точнее не могу понять на каком этапе и как сервер будет понимать, что к нему пытаются подконнектиться? Обычно это просходит когда колбек сервера возвращает XTYP_CONNECT в котором мы и сравниваем идентификаторы строк сервисов. Но в моем приложении колбек даже не вызывается клиентом.


Вобщем опять ай нид хелп.(
сервер и клиент прилагаю ниже:

сервер             клиент

Это сообщение отредактировал(а) wallstreet - 22.9.2011, 20:38
PM MAIL   Вверх
Estranged
Дата 23.9.2011, 23:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Названия сервера не совпадает, топик и айтемом тоже не совпадает. Я бы удивился, если бы соединился клиент. smile 

Уберите приведение типа - все станет понятно:
Код

        hszService = DdeCreateStringHandle(idInst, (LPCWSTR)szService, CP_WINANSI);
        hszTopic = DdeCreateStringHandle(idInst, (LPCWSTR)szTopic, CP_WINANSI);
        hszItem = DdeCreateStringHandle(idInst, (LPCWSTR)szItem, CP_WINANSI);


Можно сделать вот так:
Код

        LPCWSTR lp = (LPCWSTR) szService;
// результат в lp ВНЕЗАПНО удивит, я гарантирую это.
        hszService = DdeCreateStringHandle(idInst, (LPCWSTR)szService, CP_WINANSI);
        hszTopic = DdeCreateStringHandle(idInst, (LPCWSTR)szTopic, CP_WINANSI);
        hszItem = DdeCreateStringHandle(idInst, (LPCWSTR)szItem, CP_WINANSI);


Я уже отвечал по поводу этого: http://forum.vingrad.ru/index.php?showtopi...t&p=2398575
Читать с слов "Второе: (LPCWSTR)"hInst" это такая хитрость обойти ошибку C2664 компилятора?"

Цитата(wallstreet @  22.9.2011,  20:35 Найти цитируемый пост)
Чувствую, что в какой-то момент нужно приостановить работу сервера и каким-то образом ждать пока клиент не создаст коннект.Только как это сделать не могу понять.

Сервер не отвечает, потому что он занят:
Код

cin >> ch;

Мы заблокировали работу программы.
Чтобы сервер нам ответил, мы должны предоставить свободу работы для сервера - не блокировать его:
В свойствах проекта сервера сменить тип системы на Windows (configuration properties - linker - system)
Выглядит вот так. Вместо main написать вот это, только предварительно разберитесь с приведениями типа к LPCWSTR в части с DdeCreateStringHandle:
Код

int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR     lpCmdLine,
    int       nCmdShow)
{
    HINSTANCE hInst;
    MSG msg;

    hInst = GetModuleHandle(NULL);
    DDEServerOpen(hInst, TEXT ("Server"), TEXT ("Topic"), TEXT ("Item"));

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

    return msg.wParam;
}


Среди минусов - невозможно остановить сервер - это приложение без окон.

PM MAIL   Вверх
wallstreet
Дата 25.10.2011, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



если открываю сервер так:
Код

DDEServerOpen(hInst, TEXT ("Server"), TEXT ("Topic"), TEXT ("Item"));


выдает ошибку невозможности приобразования const wchar_t[7] в LPSTR.
Не заню правильно или нет, но открывая сервер вот так:

Код

DDEServerOpen(hInst, "Server", "Topic", "Item");


при этом строки у меня типа LPSTR, насколько я понимаю это кодировка ASCI, которую в дальнейшем конвертирую
в LPWSTR

Код

BOOL DDEServerOpen(HINSTANCE hInst, LPSTR szService, LPSTR szTopic, LPSTR szItem)
{
    cout << " Opening DDE Server..." << endl;


    // создаем переходник для ф-ции обратного вызова
    lpDdeProc = MakeProcInstance((FARPROC)DdeServerCallback, hInst);

    // инициализируем сервер в библиотеке
    if(DdeInitialize((LPDWORD) &idInst, (PFNCALLBACK)lpDdeProc, APPCLASS_STANDARD, 0))
    {
        cout << " Initializing DDE Server..." << endl;
        return false;
    }
    // после удачной инициализации получаем идентификаторы строк для сервисе
    // раздела и элемента данных
    else
    {
        // создаем строки юникод
        LPWSTR wService;
        LPWSTR wTopic;
        LPWSTR wItem;
        int lenAszService = lstrlenA(szService);
        int lenAszTopic = lstrlenA(szTopic); 
        int lenAszItem = lstrlenA(szItem);
        int lenWszService, lenWszTopic, lenWszItem;

        lenWszService = ::MultiByteToWideChar(CP_ACP, 0, szService, lenAszService, 0, 0);
        lenWszTopic = ::MultiByteToWideChar(CP_ACP, 0, szTopic, lenAszTopic, 0, 0);
        lenWszItem = ::MultiByteToWideChar(CP_ACP, 0, szItem, lenAszItem, 0, 0);

        if(lenWszService > 0) // проверка на удачную конвертацию
        {
            wService = ::SysAllocStringLen(0, lenWszService);
            wTopic = ::SysAllocStringLen(0, lenWszTopic);
            wItem = ::SysAllocStringLen(0, lenWszItem);
            ::MultiByteToWideChar(CP_ACP, 0, szService, lenAszService, wService, lenWszService);
            ::MultiByteToWideChar(CP_ACP, 0, szTopic, lenAszTopic, wTopic, lenWszTopic);
            ::MultiByteToWideChar(CP_ACP, 0, szItem, lenAszItem, wItem, lenWszItem);
            
            hszService = DdeCreateStringHandle(idInst, wService, CP_WINANSI);
            hszTopic = DdeCreateStringHandle(idInst, wTopic, CP_WINANSI);
            hszItem = DdeCreateStringHandle(idInst, wItem, CP_WINANSI);
            cout << "hszServiceServ: " << hszService << endl;
            cout << "hszTopicServ: " << hszTopic << endl;
            cout << "hszItemServ: " << hszItem << endl;

            
        }
        // регистрируем сервис
        DdeNameService(idInst, hszService, (HSZ)NULL, DNS_REGISTER);
        cout << "idInstServ = " << idInst << endl;
        cout << "DdeNameServiceServ = " << DdeNameService << endl;
        return true;
    }
}


Вроде ошибок компилятор не выдает, но и консоль не грузится. И чувствую что что-то не так.
А так, если отклониться от темы, то купил недавно книгу по Win32 ("Технология программирования на с++ win32 API приложений" Н.А.Литвиненко) в надежде хоть чуток приобрести знаний по типам данных винды, ну и вообще. Вобщем облом, развернутой инфы нет, только вскользь на пол страницы про кодировки юникод и аски в отличии от описания различных функций.
Вот реально понимаю, что тема важная, надо знать.. Но как въехать в нее, с чего начать? Столько типов разных, как понимать какой из них применять именно в этом случае ну и вообще.. Вот к примеру в моем примере строки необходимо удалять функцией SysFreeString, однако она принимает только строки типа BSTR, а у меня то LPWSTR... уууу я схожу с ума)) 
Короче мне опять нужна ваша бесценная помощь.


Ссылка на проект

Это сообщение отредактировал(а) wallstreet - 25.10.2011, 23:03
PM MAIL   Вверх
wallstreet
Дата 17.11.2011, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Господа, ларчик просто открывался))))

Код

    hszService = DdeCreateStringHandleA(idInst, szService, CP_WINANSI);
    hszTopic   = DdeCreateStringHandleA(idInst, szTopic, CP_WINANSI);
    hszItem    = DdeCreateStringHandleA(idInst, szItem, CP_WINANSI);


Это сообщение отредактировал(а) wallstreet - 17.11.2011, 15:31
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0697 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.