Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WinAPI, Thread & WM_SETTEXT, Проблемки при задании текста 
:(
    Опции темы
Dagger
  Дата 13.1.2005, 02:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 377
Регистрация: 4.9.2002
Где: Киев

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



Ситуация такая.

Вызывается тред..
в нем вызывается функция,в которой


Код

SendDlgItemMessage(hwnd, TXT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)text);



До этого вызываются функции, где есть (ну понятно, прогресбары) и код

Код

   SendDlgItemMessage(hwnd, BAR, PBM_SETRANGE, 0, MAKELPARAM (0, Maxval));
   SendDlgItemMessage(hwnd, BAR, PBM_SETSTEP, (WPARAM)Step, 0); // mit jedem Schritt 10% weiter
   SendDlgItemMessage(hwnd, BAR, PBM_SETPOS, (WPARAM)progress, 0);


проблема в том, что если вызывать только функции работы с прогресбаром - все прекрасно работает, ползунки бегают как и положено. Но если хоть раз вызвать функцию, где есть месседж WM_SETTEXT , то все прогрессбары тут же прекращают работу, текст задается как-то через раз и в непонятном мне порядке... что делать? почему так? принцип мож какой там естЬ, который мне недоступен smile

Спасибо!
PM MAIL WWW Skype   Вверх
zhgutov
Дата 13.1.2005, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А что еще происходит в коде треда?
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Dagger
Дата 13.1.2005, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 377
Регистрация: 4.9.2002
Где: Киев

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



Вот основной код. На изящество обращать внимания не стоит, да))
Код


DWORD WINAPI _TH_SendMail_func( LPVOID p ){
struct _TH_SendMail *arg = (struct _TH_SendMail *)p;
char buf[SBC_EMAIL_FLEN * SBC_P_USERS + SBC_P_USERS + 2000];
const int s_Len = 20;
char str[s_Len];
double percent1;
int prgrs1 = 0;
int prgrs2 = 0;
FORMDATA body;
char *url;
int prev = 0;
char *psz;
int i = 0, j = 0, k = 0, n = 0;
DWORD begin;

k = 0;
memset(&buf, '\0', SBC_EMAIL_FLEN * SBC_P_USERS + SBC_P_USERS + 2000);

PB_OnlyReset(arg->wnd, NS_CURRENT_PROGRESS, SBC_P_USERS, 0);
PB_OnlyReset(arg->wnd, NS_TOTAL_PROGRESS, 1, 0);

percent1 = (int)( (nc_data->c_users - arg->begin) / 100);

for(i = arg->begin; i < nc_data->c_users; i++){

 memset(&str, '\0',  s_Len);

 psz = NULL;
 url = NULL;

 //PB_Text(arg->wnd, NS_SD_INFOBOX, "Парсинг адресов...");
 //! - если тут раскомментировать все прекращает работать

 if(k++ == SBC_P_USERS || (i+1) == nc_data->c_users){
  body = _SetValue("body", buf);
  url = _Add4Query(url, body);

  if(!url){
   return 0;
  }



  psz = LoadData(arg->wnd, NS_SD_NET_PRGRS, 0 /* NS_SD_INFOBOX */, SCRIPT_SUBSCRIBE,
    "step4", url, 1);
   //а если здесь раскоментировать и заменить 0 на NS_SD_INFOBOX - тоже
   //все прекращает работать. Функция LoadData - открывает соединение
   //с сервером, по ходу покаызвает что делает в текстовом поле и  
   //двигает програсбар



  /*
   if(!psz){
    PB_Text(arg->wnd, NS_SD_INFOBOX, "Ошибки!");
    //return 0;
   }
  */

  PB_Step(arg->wnd, NS_CURRENT_PROGRESS);

  free(url);
  free(psz);

  memset(&buf, '\0', SBC_EMAIL_FLEN * SBC_P_USERS + SBC_P_USERS + 2000);
  k = 0;

  // timeout
  begin = GetTickCount();
  prev = begin;
  PB_OnlyReset(arg->wnd, NS_SD_NET_PRGRS, 1, 0);
  while(begin + SBC_REQUEST_TIMEOUT > GetTickCount()){
   if(GetTickCount() > prev + SBC_REQUEST_TIMEOUT/100){
    prev = GetTickCount();
    PB_Step(arg->wnd, NS_SD_NET_PRGRS);
   }
  }
  //---

  PB_OnlyReset(arg->wnd, NS_CURRENT_PROGRESS, SBC_P_USERS+1, 0);
  PB_OnlyReset(arg->wnd, NS_SD_NET_PRGRS, 1, 0);
 }

 if(n++ >= percent1){
  n = 0;
  PB_Step(arg->wnd, NS_TOTAL_PROGRESS);
 }

 if(nc_data->usr[i].mail){
   sprintf(str, "%d", i);
   strcat(buf, str);
   strcat(buf, "\\");
   strcat(buf, nc_data->usr[i].mail);
   strcat(buf, "|");
   PB_Step(arg->wnd, NS_CURRENT_PROGRESS);
 }

 arg->total_prgrs++;
 //sprintf(str, "%d", arg->total_prgrs);
 //PB_Text(arg->wnd, NS_TOTAL_PROGRESS_STR, str);
   //та ж история


}

PB_OnlyReset(arg->wnd, NS_TOTAL_PROGRESS, 1, 100);
return 0;
}


PM MAIL WWW Skype   Вверх
zhgutov
Дата 13.1.2005, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



LoadData, PB_Step, PB_OnlyReset, PB_Text - это все абстракция? Если так, то, быть может, в них проблема? Хороший способ проверить - сделать трассировку всего-всего. Ищешь место сбоя, затем подробно анализируешь код до сбоя. А потом: что значит прекращает работать? А можно код хоть одной вышеперечисленной функции?
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Dagger
Дата 13.1.2005, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 377
Регистрация: 4.9.2002
Где: Киев

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



Где-то так. Кода много.. написал для облегчения жизни своей smile)..

Код

int PB_Reset(HWND hwnd, int BAR, int TXT, int Step){
   SendDlgItemMessage(hwnd, BAR, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
   SendDlgItemMessage(hwnd, BAR, PBM_SETSTEP, (WPARAM) Step, 0); // mit jedem Schritt 10% weiter
SendDlgItemMessage(hwnd, TXT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)"");
return 0;
}
int PB_OnlyReset(HWND hwnd, int BAR, int Step, int progress){
   SendDlgItemMessage(hwnd, BAR, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
   SendDlgItemMessage(hwnd, BAR, PBM_SETSTEP, (WPARAM)Step, 0); // mit jedem Schritt 10% weiter
SendDlgItemMessage(hwnd, BAR, PBM_SETPOS, (WPARAM)progress, 0);
return 0;
}

int PB_Text(HWND hwnd, int TXT, char *text){
SendDlgItemMessage(hwnd, TXT, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)text);
return 0;
}

int PB_Step(HWND hwnd, int BAR){
   SendDlgItemMessage(hwnd, BAR, PBM_STEPIT, 0, 0);
return 0;
}




и еще функции работы с сервером:

Код




char *GetString(HWND hdlg, int BAR, SOCKET s) {
char InBuff[S_MEMBLOCK];
char *buffer = NULL;
char *tmp = NULL;
int cnt;
int memsize = S_MEMBLOCK+1;
int steps = 0;
int len = 0;

buffer = (char *)malloc(1);
memset(buffer, '\0', 1);

strcpy(buffer, "");

PB_OnlyReset(hdlg, BAR, 10, 0);

while (cnt != 0) {
 memset((char *)&InBuff, '\0', S_MEMBLOCK);
 cnt=recv (s, (char*)&InBuff, S_MEMBLOCK-1,0);

  len = strlen(buffer);
  buffer = (char *)realloc(buffer, len + cnt + 1);
  strcat(buffer, InBuff);

 if(steps > 100-10){
  //PB_Reset(hdlg, BAR, 0, 10);
  steps = 0;
  PB_OnlyReset(hdlg, BAR, 10, 0);
 }else{
  PB_Step(hdlg, BAR);
  steps += 10;
 }

}
PB_OnlyReset(hdlg, BAR, 1, 100);
return buffer;
}


char *LoadData(HWND hwnd, int BAR, int TXT, char *host, char *query, char *request, int method){
char *string = NULL;

if( (string = OpenURL(hwnd, BAR, TXT, host, query, request, method)) != NULL){
 CloseURL();
 string = strstr(string, "\r\n\r\n");
 string += 4;
 return string ? string : NULL;
}

CloseURL();
return string;
}

char *OpenURL(HWND hwnd, int BAR, int TXT, char *http_host_ex, char *query, char *request_data, int method) {
char *none="";
char *psz;
char *http_path = NULL;
char *http_host = NULL;
char *request = NULL;
struct sockaddr_in ssin;
struct hostent* hp;


int PortNum = 80;

char cBuffer[256];

http_host = strdup(http_host_ex);
http_path = http_host;

if(strncmp(http_host, "HTTP://", 7) == 0 || strncmp(http_host, "http://", 7) == 0){
 http_path += 7;
}

if(http_path){
 http_path = strchr(http_path, '/');
 if(http_path == NULL){
  http_path = (char *)malloc(1);
  *http_path = 0;
 }else{
  http_path++;
  psz = (char *)malloc(strlen(http_path) + 1);
  memset(psz, '\0', strlen(http_path) + 1);
  memcpy(psz, http_path, strlen(http_path));

  *(--http_path) = 0;
  http_path = psz;
  psz = strchr(http_host, '/');

  if(psz){
   *psz = 0;
  }
 }
}

PB_Reset(hwnd, BAR, TXT, 1);
PB_Text(hwnd, TXT, "Инициализация соеднинения...");
PB_Steps(hwnd, BAR, 5);

if (WSAStartup(MAKEWORD(1,1),&lpWSAData)!=0)return NULL;

PB_Steps(hwnd, BAR, 20);


// Поучаем IP по имени

PB_Text(hwnd, TXT, "Запрос DNS...");

if ((hp = gethostbyname(http_host)) == NULL)return NULL;

PB_Steps(hwnd, BAR, 30);


memset ((char *)&ssin, 0, sizeof(ssin));
ssin.sin_family = AF_INET;
ssin.sin_addr.s_addr = htonl(INADDR_ANY);
ssin.sin_port = 0;
bind (s, (struct sockaddr *)&ssin, sizeof(ssin));

s=socket(AF_INET, SOCK_STREAM, 0);
if (s==INVALID_SOCKET)return NULL;

ssin.sin_family = AF_INET;
ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];
ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];
ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];
ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];
ssin.sin_port = htons(PortNum);


sprintf(cBuffer, "Подключение к %d.%d.%d.%d...",
 (unsigned char)hp->h_addr[0],
 (unsigned char)hp->h_addr[1],
 (unsigned char)hp->h_addr[2],
 (unsigned char)hp->h_addr[3]);


PB_Text(hwnd, TXT, cBuffer);

if (connect(s, (struct sockaddr *)&ssin, sizeof(ssin)) == -1)return NULL;

PB_Steps(hwnd, BAR, 30);

switch(method){
 case 1:
  request = PostRequest(http_host, http_path, query, request_data);
  break;
 default:
  request = GetRequest(http_host, http_path, query);
  break;
}


if(!request)return NULL;

PB_Text(hwnd, TXT, "Запрос данных...");

if (!SendString(s,request))return NULL;

free(request);
free(http_path);
free(http_host);

PB_Steps(hwnd, BAR, 20);

PB_Reset(hwnd, BAR, TXT, 1);
PB_Text(hwnd, TXT, "Загрузка данных...");


return GetString(hwnd, BAR, s);
}


PM MAIL WWW Skype   Вверх
zhgutov
Дата 14.1.2005, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Одно уже вижу:
Код

char InBuff[S_MEMBLOCK];
// ...
memset((char *)&InBuff, '\0', S_MEMBLOCK);
cnt=recv (s, (char*)&InBuff, S_MEMBLOCK-1,0);

Фишка в том, что C++, равно как и C, интерпретируют массив как указатель. В данном случае InBuff — это char*, а &InBuff — char**, поэтому:
Код

char InBuff [S_MEMBLOCK];
// ...
memset (InBuff, '\0', S_MEMBLOCK);
cnt = recv (s, InBuff, S_MEMBLOCK - 1, 0);

А если тип — не char, то так:
Код

T InBuff [S_MEMBLOCK];
memset (InBuff, byte, S_MEMBLOCK * sizeof (T));


Идем далее:
Код

char* LoadData (HWND hwnd, int BAR, int TXT, char* host, char* query, char* request, int method)
{
   char* string = NULL;

   if ((string = OpenURL (hwnd, BAR, TXT, host, query, request, method)) != NULL)
   {
       CloseURL ();
       string = strstr (string, "\r\n\r\n");
       string += 4;
       return string? string: NULL;
   }

   CloseURL ();
   return string;
}

А кто выделяет память под string? Кто ее потом освобождает? Каким образом освобождает?

Код

string += 4;
return string? string: NULL;

После выполнения первого выражения, !string всегда false.
Код

char* strstr (
  const char* string,   // Null-terminated string to search
  const char* strSearch // Null-terminated string to search for
);

«Returns a pointer to the first occurrence of strSearch in string, or NULL if strSearch does not appear in string. If strSearch points to a string of zero length, the function returns string» — MSDN.

Это сообщение отредактировал(а) zhgutov - 14.1.2005, 14:12
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Dagger
Дата 17.1.2005, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 377
Регистрация: 4.9.2002
Где: Киев

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



Цитата
А кто выделяет память под string? Кто ее потом освобождает? Каким образом освобождает?


функция GetString


Цитата


Код

string += 4;
return string? string: NULL;

После выполнения первого выражения, !string всегда false.


на самом деле оно работает. По ходу я не вижу ошибки. Там такая фишка, что функция OpenURL либо возвращает NULL, либо возвращает строку. Конечно, не все идеально, но работает оно на "ура" - 4 раза информация берется с сервера и каждый раз она адекватная и обрабатывается хорошо.


Цитата
Фишка в том, что C++, равно как и C, интерпретируют массив как указатель. В данном случае InBuff — это char*, а &InBuff — char**, поэтому:



Спасибо. я как-бы это не до конца понимал. Но странно то, что оно работало. Хотя, когда я последовал твоим советам оно рабоало(ет) тоже ;)))


В итоге, легче не стало smile
PM MAIL WWW Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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