Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Изменение размера формы

16K
26 сентября 2006 года
PupaJr
20 / / 14.09.2006
Вот код(вырезанные куски):

Эта процедура инициализирует координаты всех окон на форме в момент её инициализации в 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);
В неё все параметры входят нормальные а при её вызове система глючит или сбой доступа памяти. Дальше естественно форма отображается не правильно или вообще программа "вываливается". Такое ощущение что сама программа портит свои данные или использует "общественный" участок памяти для хранения данных формы, которые другими процедурами портятся хотя они никак не касаются формы и отсюда нарушения. Как защитить данные?

Может всего много и что-то не понятно, пишите, постараюсь развернуть подробнее....
3.0K
26 сентября 2006 года
Мerlin
267 / / 25.07.2006
Здесь вроде все нормально.
Если есть переменные типа char[], то имеет смысл посмотреть все операции strcpy/strcat/sprintf. Там может быть затирание памяти.
Типа в переменную char[10] копируется переменная char[20].
16K
27 сентября 2006 года
PupaJr
20 / / 14.09.2006
Я думал над этим вопросом, что нарушается распределение памяти или защиты или вообще это глюк компилятора. Пробывал ставить уровень ошибок W4 а не W3, так там куча всего вылазит, типа не все входящие параметры используются, старое объявление переменных, пременные не инициализируются (хотя в теле программы в них пишутся данные), ну и т.п., не серьёзные. Того что написали Вы - нарушение размерности нет, просмотрел. Пробывал на дебаггере прокрутить код до места "Ч", но у меня ругается дебаг - пишет нет DBG file и не запускается отладка, и не ставит брек-поинты - типа сюда программа никогда не заходит и точка останова бесмыслена... - видимо косяк инсталляции..
Какие ресурсы памяти ещё затрагиваются и как это можно отследить....?? Может есть какие ключи компилятора, позволяющие подробнее просмотреть весь процесс компиляции???
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог