Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вопрос по использованию GridEdit1153  (Прочитано 20158 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Lotor
Гость
« : 09-05-2008 16:09 » 

<...> (немного не с начала)

Алексей1153++, Я Вам на мыло "стучал", согласен обсуждать тут =)

Джон, В 2005, например, for(int i;i<100;i++) i будет распространяться только на блок цикла...
« Последнее редактирование: 08-03-2009 17:36 от Алексей1153++ » Записан
Lotor
Гость
« Ответ #1 : 17-05-2008 18:52 » 

Алексей1153++, ещё вопросик.  У меня сейчас приложение клиент-сервер. На обоих твой грид. Клиент спрашивает таблицу строк у сервера и тот их выдает. Всё хорошо, но моргает. Ужасно моргают ячейки. Может я неправильно в них запихиваю данные?
Код:
for (int i=0;i<ppGR->GetRows();i++)
for (int j=0;j<ppGR->GetCols();j++)
{
buf=strRecvd.SpanExcluding(razdelitl);
ppGR->SetCellTextSTR_not_saved(i,j,buf);
ppGR->Invalidate(0);
iLen=buf.GetLength();
strRecvd=strRecvd.Mid(iLen+1);
}

Можно ли как-нибудь избавиться от мерцаний? Как вариант делать ppGR->Invalidate(0) по таймеру мне только приходит.

Добавлено: Мерцания получаются, потому что сервер может изменять размерность таблицы. Т.е. сначала клиент спрашивает размерность, по полученным данным перерисовывает таблицу и только потом запрашивает данные. Мерцания получаются, из-за перерисовки таблицы. Так или иначе, можно ли избавиться от мерцаний даже перерисовывая таблицу?)
« Последнее редактирование: 17-05-2008 19:02 от Lotor » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 17-05-2008 19:02 » 

вообще то, моргать нифига не должны - это изначально заложено при написании класса , скоре всего , это ты что то не так делаешь )
Отрисовку в классе не менял ?
Может фон диалога перерисовываешь ?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 17-05-2008 19:03 » 

ааа, кажись понял


ppGR->Invalidate(0);
 - это поставь после обоих for
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #4 : 22-05-2008 06:57 » 

Суть проблемы: не могу прикрутить этот класс к пробному проэкту, потому что  в проэкте, то окно где должен располагаться грид создаётся динамически(через вызов Create), соответсявенно контролл CStatic создаю тоже через вызов Create. При запуске программа завершается с ошибкой. Ошибку вызывает макрос DDX_Control(pDX, IDC_GRID, m_IDC_GRID); в классе моего окна.

Как решить эту проблемму? Я так понимаю надо макрос чем-то заменить?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 22-05-2008 07:39 » 

Hobotanius, не пойму проблемы ...

Для начала - в чём пишешь ? Ну вроде MFC . Всё по инструкции делал? Ага
 Если да, то пришли проект свой, я гляну, в чём проблема

Макрос не надо заменять - это визард связал контрол на форме с экземпляром класса - m_IDC_GRID

Цитата
соответсявенно контролл CStatic
вот это больше всего непонятно - тут не надо создавать CStatic
« Последнее редактирование: 22-05-2008 07:41 от Алексей1153++ » Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #6 : 22-05-2008 08:04 » 

Макрос не надо заменять - это визард связал контрол на форме с экземпляром класса - m_IDC_GRID

вот это больше всего непонятно - тут не надо создавать CStatic

В инструкции CStatic на форму кладётся и флаги - SS_SUNKEN, SS_NOTIFY нужно установить. Разве нет?
Но у меня нет формы! Я создаю это окно вызовом Create, и CStatic тоже.

Куды прислать проэкт?
Записан
Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #7 : 22-05-2008 11:59 » 

Вот прикрепил к посту.
Сейчас при компиляции будет ошибка, чтоб её не было надо закоментировать
DDX_Control(pDX, IDC_GRID, m_IDC_GRID);
в файле GridTestDlg.cpp
« Последнее редактирование: 11-03-2009 23:45 от Алексей1153++ » Записан
Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #8 : 22-05-2008 12:13 » 

В этом проэкте главное окно создаётся из шаблона, но CStatic создаю в OnInitDialog.
Если закоментировать DDX_Control(pDX, IDC_GRID, m_IDC_GRID); , то ошибка исчезает, но в окне грида ни чего не отображается.
Можно закоментировать -
m_StatGrid.Create(NULL, WS_CHILD | WS_GROUP | WS_VISIBLE | SS_SUNKEN | SS_NOTIFY, rc, this, IDC_GRID);
и добавить его в шаблоне. С DDX_Control всё отлично как и надо, а без - то не отображает таблицу как и выше.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 22-05-2008 17:39 » 

Hobotanius, так, а я чёта не понял: диалог у тебя есть (IDD_GRIDTEST_DIALOG). А контрол на нём не лежит. Ты, видимо, раньше ставил его туда, а потом неаккуратно замочил ) А макрос остался, вот прогроамма и вылетает - хендл то ==0
« Последнее редактирование: 11-03-2009 23:45 от Алексей1153++ » Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #10 : 23-05-2008 04:19 » 

Алексей1153++, я об этом тебе и говорю. Что нужно статик-контрол создавать программно! Если я его программно создаю т.е. функцией Create, то как сделать чтоб всё работало?
Инструкцию я читал, но в ней ни слова о том как поступать в случае если статик-контрол необходимо создавать программно, а не в шаблоне.
Ещё раз повторюсь: в проэкте к которому я пытаюсь прикрутить грид содержится ТАВ-контролл, и грид должен быть расположен на одной из вкладок ТАВ-контролла. Вкладки ТАВ-контролла создаются НЕ В ШАБЛОНЕ, А ПРОГРАММНО с помощью Create, поэтому и статик-контрол приходится создавать программно (т.е. не в шаблоне а во время инициализации главного окна программы). Поэтому я удалил статик-контролл из шаблона. а в InitDialog вставил стоку -    m_StatGrid.Create(NULL, WS_CHILD | WS_GROUP | WS_VISIBLE | SS_SUNKEN | SS_NOTIFY, rc, this, IDC_GRID);. Но при этом если возникает ошибка если оставить строку - DDX_Control(pDX, IDC_GRID, m_IDC_GRID);, в противном случае (если строку DDX_... замочить, то таблица не отображается).
Вот... Об этом я и писал. Очень надеюсь на помощь, а то просто затык какой-то.
« Последнее редактирование: 23-05-2008 04:25 от Hobotanius » Записан
Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #11 : 23-05-2008 07:54 » 

Мешает разрешение экрана - оно может быть разным вот поэтому расчитываю размеры окон и контроллов в процентах а затем создаю их динамически.

Всё так и сделал
Только что-то не пойму - а как теперь задать размеры таблицы?
Ведь - BOOL CGridEdit1153::Create(CWnd* pParent), берёт только 1 параметр...
А вызывая эту функцию ни чего не создаётся. =(
Хотя функция возвращает TRUE.
« Последнее редактирование: 23-05-2008 07:59 от Hobotanius » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 23-05-2008 08:07 » 

Цитата
Мешает разрешение экрана - оно может быть разным вот поэтому расчитываю размеры окон и контроллов в процентах а затем создаю их динамически.
не вижу тут проблемы - в помощь тебе функции

Код:
CWnd::GetClientRect
CWnd::GetWindowRect
CWnd::MoveWindow
::GetSystemMetrics() // с параметрами SM_CXSCREEN, SM_CYSCREEN
::MapWindowPoints
и это нифига не повод отказываться от редактора ресов Улыбаюсь
А кроме того - таб контрол можно положить на диалог, к которому приделать полоски прокрутки - тогда вообще забудешь про разрешение. Я делал такой проект

Цитата
Только что-то не пойму - а как теперь задать размеры таблицы?
Ведь - BOOL CGridEdit1153::Create(CWnd* pParent), берёт только 1 параметр...
мануал снова не прочитал ? Улыбаюсь А там есть даже проект с примером

тебе нужна функция SetRowsCols()
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #13 : 23-05-2008 08:28 » 

Видимо я не так выразился не размеры таблицы, а размер грид-контролла (CRect).
Неправда. Всё я прочитал.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 23-05-2008 08:39 » 

Hobotanius, во первых, задавай на диалоге размер статика - и по умолчанию размер грида совпадёт с.
А если надо менять в динамике - вот жжжентельменский набор функций
Код:
CWnd::GetClientRect
CWnd::GetWindowRect
CWnd::MoveWindow
::GetSystemMetrics() // с параметрами SM_CXSCREEN, SM_CYSCREEN
::MapWindowPoints

после того, как Create таблицу, можешь пользоваться этими функциями для изменения размеров грида

-------------
а вообще, такое ощущение, что что то ты недоговариваешь Улыбаюсь Пока я не вижу проблемы, но может я просто что то не знаю, уточни, будем разбираться
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #15 : 23-05-2008 12:44 » 

Упс!!! А вот это уже странно!
Припоследнем изменении (модификации стиля) Заработал только клик мышой и горизонтальный скроллбар. А вертикальный не работает и нажатия клавишь тоже!

* GridTest.rar (85.37 Кб - загружено 796 раз.)
Записан
Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #16 : 26-05-2008 06:08 » 

<...>
Да не вопрос! Не-а... Просто решил сообщить о ситуации, которая, как мне кажется, не совсем корректна. Возникает она если стрелками увести курсор на ячейки таблицы, которые находятся за пределами видимости и нажать интер, то откроется окошко редактирования ячейки. Может открыться даже за пределами главного окна программы.
« Последнее редактирование: 11-03-2009 23:49 от Алексей1153++ » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 26-05-2008 06:25 » 

теперь понял )
Ну, это можно и исправить, подумаю. Можно при нажатии на ентер перемотать таблицу, чтоб ячейка показалась на экране, а можно просто запретить там открыть

кстати, ты это в своём обработчике можешь сделать
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #18 : 27-05-2008 10:39 » 

в общем вот проэкт где я добавил 9 функций-членов и две переменные в класс грида.
Все добавленные функции объявлены рядом друг с другом, для удобства.
Все изменённые функции имеют закоменчинный оригинальный экземпляр в файле GridEdit1153.cpp.
Функциональные изменения:
1. Добавлена возможность отрисовывать простой квадрат вместо краснеющего треугольника.
2. Добавлена возможность отрисовывать длинный курсор (на все колонки)
3. Добавлена автоскроллирование таблицы вслед за курсором.
4. Добавлен запрет редактирования ячейки если она за пределами видимости.
Если кто-то найдёт в них ошибки - пожалуйста сообщайте.

* GridTest.rar (90.3 Кб - загружено 738 раз.)
Записан
Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #19 : 29-05-2008 05:19 » 

Алексей1153++, кажется функция
DWORD CGridEdit1153::GetVisibleRows()
возвращает больше чем реально строк на экране.

Вот последняя версия этого проекта.
Устранены все ошибки которые только смог найти.
Для удобства в конце файла GridEdit1153.cpp перечислил функции,
которые были изменены (имеют закомментированный оригинал).

* GridTest.rar (90.05 Кб - загружено 791 раз.)
« Последнее редактирование: 29-05-2008 10:57 от Hobotanius » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 29-05-2008 17:07 » 

кажется функция
DWORD CGridEdit1153::GetVisibleRows()
возвращает больше чем реально строк на экране.
кажется или точно ? ) Она возвращает столько, сколько на экране видно, даже если от последней видно всего 1 пиксел

Проект скачал, только щас смотреть не могу - устал )

Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 29-05-2008 19:52 » 

Hobotanius, посмотрел. Спасибо за тестирование и предложенные исправления Улыбаюсь

однако, в итоге

1) ну, с конструктором всё понятно

2) GetVisibleRows() - сделаю поправку - буду возвращать ещё параметр, где будет указано, сколько процентов неполной видно строки видно в конце (так как строка может быть обрезана нижним краем грида)

3) SetCursorCol_zb(),SetCursorRow_zb() - обдумаю. Наверное, в качестве ещё одного параметра передам флаг - корректировать ли или нет окно просмотра , а то, может, этого и не нужно делать )

4) CGridEdit1153::SetRedTopRow() - у тебя и запутано по логике. Я сделаю проще: если включено "краснение", будет треугольник, если не включено - будет всегда серый квадрат

5) OnPaint() всё понятно

6) PaintGrid() -
Код:
if(nLastTableWidth>20000)nLastTableWidth=2000;
m_HBar.SetScrollRange(0, /*nLastTableWidth*/ GetWidthTable() - GetWidthWindowForTable() - 1,0); // &&&
тут не всё так просто, я так не сделаю Улыбаюсь Надо именно nLastTableWidth (кстати, не 2000, а 20000 в конце строки. Это я уже исправил, в новом варианте будет норм). Это когда у тебя ширина таблицы меньше 0x7fff , всё , возможно, будет нормально, а дальше начнётся фигня. Я подумаю, может сделать вообще - когда ширина таблицы слишком большая, скролить сразу по ячейкам, а не по пикселам

7) SendNotifyMessToParent()

>>
Код:
case CGridEdit1153::IDmess_OnVScroll_slidermove:
{
if(NI.dwdLogicNumberOfRows)
{// &&& - GetFitRows() вместо -1 чтоб при опущеном ползунке отображалось строк столько сколько вмещается в окно, а не одна - последняя строка
DWORD dwd=(DWORD)(((double)(NI.dwdLogicNumberOfRows - GetFitRows()))*NI.pVBI->GetWherePerCent());
SetTopRow_zb(dwd);
Invalidate(0);
}
}
break;
спорный момент , может по флажку надо будет сделать. Вообще то, можно в обработчике сообщений задать логическое количество строк MAX-видно_на_экране и будет тот же эффект. А вот, к примеру, ползунок стоит посередине, а снизу не видно, последняя там строка или нет - нужно будет прокрутить ползунок до конца, чтоб это понять. А когда последнюю строку видно так, когда она "в воздухе" - тут однозначно всё ясно. А кроме того - никто из пользователей не пожаловался на эту висячую строку , а это показатель Улыбаюсь А пользователей много и они разные.

>>
Код:
case CGridEdit1153::IDmess_OnMouseWheel:
case CGridEdit1153::IDmess_OnVScroll_arrowup:
case CGridEdit1153::IDmess_OnVScroll_arrowdown:
case CGridEdit1153::IDmess_OnVScroll_placeup:
case CGridEdit1153::IDmess_OnVScroll_placedown:
{

// &&& +1 Чтоб щёлкая по пространству бегунка дойти до последней стороки иначе до предпоследней
if(NI.dwdLogicNumberOfRows)
{
MoveRowsReturnIsMoved(NI.pVBI->tomovevalue,true,true,NI.dwdLogicNumberOfRows - GetFitRows() +1);
}
}
break;
см. пункт 3
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 29-05-2008 20:10 » 

по твоим добавленным функциям:

1) GetIndexColBesideLEdge(),- уже есть , GetLefCol_zb()
2) GetIndexColBesideREdge() нету (у меня было бы GetRigCol_zb) , только нигде и не понадобилось, вот и нету Улыбаюсь
3) GetWidthTable() - зачем вычислять ширину таблицы, она уже вычислена при последней отрисовке, это переменная nLastTableWidth в методе PaintGrid. Тем более, что нигде, кроме как там, ты GetWidthTable не вызвал Ага
4) GetFitRows() - уже есть GetVisibleRows()
5) SetNoRedTriangleDraw() - логически лишняя функция, я писал в предыдущем посте
6) SetLongCursor() - ок
7) AllowCellEdit() - по моему, лишнее. Пусть программист в обработчике сам решает, где показывать окно редактирования, тем более, что по умолчанию оно выключено, так как это для ОСОБЫХ случаев
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #23 : 30-05-2008 04:39 » 

Ой так много! Улыбаюсь
Сразу отвечу на последнее - 4 пункт.
Я так понимаю GetVisibleRows() возвращает кол-во тех строк, что видно в окне на данный момент(как написано в пояснении).
Например если сдвинули бегунок вниз и в окне отображается 5 висячих(как ты хочешь сделать по флагу) строк, то GetVisibleRows() вернёт 5. Правильно?
А GetFitRows() всегда вернёт столько сколько МОЖЕТ уместиться в окне. Т.е. например 10.
Или я ошибаюсь и GetVisibleRows() вернёт тоже 10 ? Если ошибаюсь, то тогда надо исправить комментарий Отлично.
« Последнее редактирование: 30-05-2008 04:42 от Hobotanius » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 30-05-2008 15:47 » 

да, у меня возвращает - сколько может поместиться ) А вообще - всё зависит от конкретной задачи, универсально всё равно не сделать ) Надо давать возможность менять функциональность через обработчик сообщений, а не изменением класса всё же
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #25 : 02-06-2008 07:16 » 

Протестировал функцию DWORD CGridEdit1153::GetVisibleRows();.

Условия:
Полоса прокрутки = 17
Заголовок столбца = 17
Высота окна = 234

Пример этапов расчёта внутри GetVisibleRows():
Первый расчёт:
234 – 17 – 17 = 200 – здесь всё правильно. Программа, калькулятор и дублирующий расчёт выдают один результат.

Второй расчёт:
200 / 18 = 11.(1)  - калькулятор выдал 11 и 1 в периоде после точки.
200 / 18 = 11 – выдал дублирующий расчёт.

Код:
// Дублирующий расчёт
AfxMessageBox(""+MyGlobals::ToString(ldcH / m_wRowHeight) +" = "
+MyGlobals::ToString(ldcH) +" / "
+MyGlobals::ToString(m_wRowHeight)
             );


200 / 18 = 12 – вернула функция

Код:
void CGridTestDlg::OnButtonLeftcol()
{
// Смотрим что вернёт GetVisibleRows()
AfxMessageBox(MyGlobals::ToString((long)m_pGrid->GetVisibleRows()));

}

Ручной пересчёт точек показал, что две точки по высоте в расчёте учтены небыли. Эти точки составляют высоту дополнительных окантовок.
Ошибку вносит отчасти не учёт этих точек, отчасти авто-округление.
  Но вот я делаю размер контролла на единицу меньше и уже не две точки окантовки надо учитывать, а одну. Может стоит добавить авторегулирование контролла, чтоб подгонял под содержимое. Или возможность задавать высоту в строках таблицы.
« Последнее редактирование: 02-06-2008 09:53 от Hobotanius » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 02-06-2008 15:16 » 

Hobotanius, насчёт окантовок - скорее всего я где то применил не GetClientRect , а GetWindowRect . А просто сдвиг на 2 пиксела не спасёт - во уберут ту же рамку и всё ) Сорри, разбираться щас некогда (( Аврал...
Записан

Hobotanius
Интересующийся

ru
Offline Offline

« Ответ #27 : 03-06-2008 04:12 » 

Это не запара, у себя я уже сделал в прошлом примере - просто отнимаю 2, но видимо надо отнимать 1 и на 1 уменьшить высоту контролла. И просто помнить что высота контролла должна равняться высоте заголовка плюс высота полосы прокрутки плюс количество видимых строк умножить на высоту строки, и плюс один.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 03-06-2008 08:07 » 

Цитата
И просто помнить что высота контролла должна равняться высоте заголовка плюс высота полосы прокрутки плюс количество видимых строк умножить на высоту строки, и плюс один.
это всё вторично, главное - высота контрола равна высоте прямоугольника, полученного через GetClientRect(). От этого надо плясать и в PaintGrid и при расчёте высоты
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines