Форум программистов CodeGuru
23 Апрель 2018, 21:28:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Изменение размера формы  (Прочитано 16764 раз)
0 Пользователей и 1 Гость смотрят эту тему.
PupaJr
Пользователь
***
Офлайн Офлайн

Сообщений: 33


Просмотр профиля
« : 28 Сентябрь 2006, 17:22:20 »

Вот код(вырезанные куски):

Эта процедура инициализирует координаты всех окон на форме в момент её инициализации в WM_INITDIALOG:

Код:
void childresize_init(HWND hwndDlg, ChildWndResizeItem *list, int num)
{
RECT r;
GetClientRect(hwndDlg,&r);
int x;
for (x = 0; x < num; x ++)
{
RECT r2;
GetWindowRect(GetDlgItem(hwndDlg,list[x].id),&r2);
ScreenToClient(hwndDlg,(LPPOINT)&r2);
ScreenToClient(hwndDlg,((LPPOINT)&r2)+1);
// char asdf[128];
// sprintf(asdf,"%u %u %u",list[x].id,x,list[x].type);
// MessageBox(NULL,asdf,"Инит положения",MB_OK); //проверка
if (list[x].type&0xF000) list[x].rinfo.left=r.right-r2.left;
else list[x].rinfo.left=r2.left;
if (list[x].type&0x0F00) list[x].rinfo.top=r.bottom-r2.top;
else list[x].rinfo.top=r2.top;
if (list[x].type&0x00F0) list[x].rinfo.right=r.right-r2.right;
else list[x].rinfo.right=r2.right;
if (list[x].type&0x000F) list[x].rinfo.bottom=r.bottom-r2.bottom;
else list[x].rinfo.bottom=r2.bottom;
list[x].type|=0xf0000;
// sprintf(asdf,"%u %u %u %u",list[x].rinfo.left,list[x].rinfo.top,list[x].rinfo.right,list[x].rinfo.bottom);
// MessageBox(NULL,asdf,"Инит положения",MB_OK); //проверка
}
}

//------------------------------------------------------------
Эта процедура вызывается по WM_SIZE:

void childresize_resize(HWND hwndDlg, ChildWndResizeItem *list, int num)
{
RECT r;
GetClientRect(hwndDlg,&r);
int x;
HDWP hdwpppx=BeginDeferWindowPos(num);
for (x = 0; x < num; x ++)
// if (list[x].type&0xf0000)
{
// MessageBox(NULL,"gtrshsh","начало процесса",MB_OK); //проверка
RECT r2;
if (list[x].type&0xF000) r2.left=r.right-list[x].rinfo.left;
else r2.left=list[x].rinfo.left;
if (list[x].type&0x0F00) r2.top=r.bottom-list[x].rinfo.top;
else r2.top=list[x].rinfo.top;
if (list[x].type&0x00F0) r2.right=r.right-list[x].rinfo.right;
else r2.right=list[x].rinfo.right;
if (list[x].type&0x000F) r2.bottom=r.bottom-list[x].rinfo.bottom;
else r2.bottom=list[x].rinfo.bottom;

HWND h=GetDlgItem(hwndDlg,list[x].id);

DeferWindowPos(hdwpppx, h, NULL, r2.left,r2.top,r2.right-r2.left,r2.bottom-r2.top, SWP_NOZORDER|SWP_NOACTIVATE);
// char asdf[128];
// sprintf(asdf,"%d %d %d %d %d %d %d %d %d", r2.left,r2.top,r2.right-r2.left,r2.bottom-r2.top,hdwpppx,x,list[x].id,hdwpp,h);
// MessageBox(NULL,asdf,"Изменение положения",MB_OK); //проверка
}
// MessageBox(NULL,"EndDeferWindowPos","Изменение положения",MB_OK); //проверка
// char asdf[128];
// sprintf(asdf,"%d",hdwpppx);
MessageBox(NULL,"rgaregh","Изменение положения",MB_OK); //проверка
if (EndDeferWindowPos(hdwpppx))
MessageBox(NULL,"111111","EndDeferWindowPos положения",MB_OK); //пров
}

//--------------------------------------------

childresize_init(hwndDlg,L_Chatroom->resize,6); //вызов инициализации

childresize_resize(hwndDlg,cli->resize,6); // вызов изменения размера
//----------------------------------------------

Сдесь выделяется память и всем объектам окна присваевается тип (как и куда им перемещаться), эта часть разная для разных форм, так как на них разные объекты (кнопки, текст, tree, edit и тд...)

chatroom_item *cli=(chatroom_item *)malloc(sizeof(chatroom_item));

memset(cli,0,sizeof(chatroom_item));
cli->resize[0].id=IDC_CHATTEXT;
cli->resize[0].type=0x0011;
cli->resize[1].id=IDC_CHATEDIT;
cli->resize[1].type=0x0111;
cli->resize[2].id=IDC_CHAT;
cli->resize[2].type=0x1111;
cli->resize[3].id=IDC_TREE1;
cli->resize[3].type=0x1011;
cli->resize[4].id=IDC_NAMELISTRESIZER; //линия разделения окна
cli->resize[4].type=0x1011;
cli->resize[5].id=IDC_CHATCHAR; // static text - число букв в сообщении
cli->resize[5].type=0x1111; //0001 - разм.вниз,0010 - разм.вправо,1000-прив.к прав. борту
}
//------------------------------------


Так вот, он работает отлично, но при изменении кода программы, который никоим образом не относится к изменении размера окна и формы, происходит искревление данных, работало раньше нормально но после изменения кода одна форма как и прежде изменяет размеры по "правилам" а во второй начинают искажаться местоположения объектов, третья тоже нормально. Делаю Clean Solution (Clean "myprog") - тоесть очищаю все obj и прочий мусор после предидущей компиляции, снова компилирую всё "BuildAll" и после этого размеры снова работают нормально, но, время от времени всёравно вылетают глюки с изменением размера - некоторые объекты формы меняют свои размеры и положение а некоторые вылетают за границы окна или их размеры становятся малыми или через чур большими - не в соответствии с размерами формы. Или того хуже вообще вышибает программу с ошибкой защиты памяти. Выяснил с помощью MessageBox_ов что виновата процедура обновления размеров -
DeferWindowPos(hdwpppx, h, NULL, r2.left,r2.top,r2.right-r2.left,r2.bottom-r2.top, SWP_NOZORDER|SWP_NOACTIVATE);
В неё все параметры входят нормальные а при её вызове система глючит или сбой доступа памяти. Дальше естественно форма отображается не правильно или вообще программа "вываливается". Такое ощущение что сама программа портит свои данные или использует "общественный" участок памяти для хранения данных формы, которые другими процедурами портятся хотя они никак не касаются формы и отсюда нарушения. Как защитить данные?

Может всего много и что-то не понятно, пишите, постараюсь развернуть подробнее....
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #1 : 28 Сентябрь 2006, 21:35:40 »

Надо делать так:
Код:
...
hdwpppx = DeferWindowPos(hdwpppx, h, NULL, r2.left,r2.top,r2.right-r2.left,r2.bottom-r2.top, SWP_NOZORDER|SWP_NOACTIVATE);

if(hdwpppx == NULL)
   // ошибка
Записан

PupaJr
Пользователь
***
Офлайн Офлайн

Сообщений: 33


Просмотр профиля
« Ответ #2 : 29 Сентябрь 2006, 16:28:06 »

Вот часть кода с ххх.h

#if defined(_WIN32)&&(!defined(_DEFINE_SRV))
   struct ChatroomItem
   {
      HWND hwnd;
      char channel[SHA_OUTSIZE*2+1];
      ChatroomItem *next;

      ChildWndResizeItem resize[5];   <-- а это моя проблема!!!

      T_GUID lastMsgGuid;
      unsigned int lastmsgguid_time;

на самом деле это число надо было не 5 а 8, так как объектов на форме было не 5 а 8, вот и было переполнение памяти resize[5] всего, а данные писались до 8 а потом читались до 8 вот и перекрывались с чужими данными программы - отсюда глюки шли..... Тупо, и детская не простительная моя ошибка.... Может кому-то подскажет, что надо следить за размерностью данных и выделенной памятью под них....
Спасибо 3V!!!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!