Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Таблица на WinAPI


Автор: yngwie19 11.3.2009, 12:59
Ребят всем привет. Я умею пользоваться поиском и видел много топиков касающихся данной темы. Однако Я все же так и не понял как сделать полноценную таблицу на WINAPI. Многие рекомендуют использовать List Control, однако это получится кастрированная таблица. И вообще возможно ли ее сделать на WinAPI или придется на MFC писать? Если не трудно приведите пожалуйста примеры готовой таблички. Большое спасибо.

Автор: dumb 11.3.2009, 15:51
Цитата(yngwie19 @  11.3.2009,  12:59 Найти цитируемый пост)
как сделать полноценную таблицу на WINAPI
что такое "полноценная таблица"? и есть ли действительная необходимость реализовывать это на WinAPI?

Автор: yngwie19 11.3.2009, 16:43
dumb, Полноценная - в моем понимании это та таблица, которая правильно выресовывается (четкие грани с разленеенными полями) и в которую можно добавлять или удалять строки. Т.к Я MFC не изучал, то пока нужно на WINAPI сделать.

Автор: Vaulter 11.3.2009, 16:50
Цитата(yngwie19 @  11.3.2009,  13:59 Найти цитируемый пост)
И вообще возможно ли ее сделать на WinAPI или придется на MFC писать?

Конечно, возможно. Вопрос времени.

А не подойдет ли уже чтото готовое? MS Excel например?

Автор: yngwie19 11.3.2009, 19:11
Vaulter, неее мне хочется самому написать. Ребят подкиньте примерчик.

Автор: GP1000 12.3.2009, 12:21
набросай на форму диалога много контролов Edito 'в и будет тебе таблица..(или пропиши создание этих окошек руками)
Можно будет и вводить текст и удалять .. А  если нужно будет обрабатывать текст в ячейках ,используешь сообщение WM_GETTEXT 

Автор: GremlinProg 14.3.2009, 20:24
жаль, что ни кто не приложился к этой теме,
а ведь на самом деле, не многие понимают как испечь пирог без рецепта
конечно, смысл не только в выводе таблицы, но и в ее модификации

по многочисленным просьбам, специально для новичков, выкладываю рецепт одного из вариантов самой простой таблицы, в которой есть возможность менять содержимое ячеек:

1. создаем простое окно
2. определяем набор данных:
Код

HWND            hwndEdit        = NULL;
CONST LONG        rows            = 30;
CONST LONG        columns            = 10;
LONG            column_width    = 90;
LONG            row_height        = 22;
LONG            sel_column        = -1;
LONG            sel_row            = -1;
BOOL            captured        = FALSE;
std::wstring    data[rows - 1][columns - 1];

это вся необходимая информация для работы нашей таблицы
hwndEdit - дескриптор редактора
rows - число строк (не меняется)
columns - число столбцов (не меняется)
column_width - ширина ячейки
row_height - высота ячейки
[sel_row:sel_column] - пара значений, в которой хранится фокусированная ячейка
captured - флаг захвата мыши (здесь реализована смена фокуса ячейки при удерживании мыши, выглядит забавно, когда к этому подмешивать ввод с клавиатуры)
data - собственно информация, которую нужно разместить в таблице
тип данных - строки юникод (ну вот, так захотелось)

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

3. рисуем сетку таблицы в обработчике WM_PAINT
4. настраиваем полосы прокрутки в обработчике WM_SIZE
5. добавляем простую прорисовку содержимого ячеек, например абсолютные номера [X:Y] и т.п.
6. рисуем фиксированную строку-столбец левым цветом, чтобы они выделялись среди прочих
7. добиваемся коректной работы "адресации окна", т.е. корректной работы полос прокрутки как при ее непосредственном участии, так и при изменении размеров таблицы, из этого:
  7.1. при прокрутке на один юнит, прокручиваем содержимое таблицы на 1 строку/столбец
  7.2. используем ScrollWindow только для двух областей: для области, в которой находятся все ячейки(не включая фиксированные строки/столбцы) и для одной из двух фиксированных строки-столбца (при горизонтальной прокрутке - это верхняя строка, при вертикальной - левый столбец)
  7.3. при автоматической прокрутке окна, т.е. без уведомлений, обновить все окно (это единственное место где обновляется окно целиком, ибо лень ) )
8. прикладываем реальные данные к таблице, т.е.задействуем вектор data при рисовании ячеек
9. делаем простой обработчик DragOver - это события WM_LBUTTONDOWN, WM_CAPTURECHANGED, WM_MOUSEMOVE, WM_LBUTTONUP
10. выделяем метод SelectCell, который будет вызываться только при смене текущей ячейки и никогда более
11. добавляем простую индикацию фокусировки: при выводе ячеек, просто утолщаем границу той ячейки, координаты которой совпадают с [sel_row:sel_column]
12. отлаживаем механизм DragOver так, чтобы при выходе мыши за границы текущего окна таблицы, фокусированная ячейка всегда оставалась в области видимости (не уходила в минуса)
13. добавляем функционал в SelectCell: создаем окно редактора (простой EDIT), если он еще не создан и назначаем ему координаты фокусированной ячейки (теперь, совместно с DragOver, редактор будет перемещаться за курсором)
14. поскольку фиксированные строка-столбец находятся в клиентской области, необходимо либо периодически скрывать редактор, если он прокручивается за окно, либо просто сдвигать фокусировку "на солнце", т.е. в видимую часть таблицы (я использовал первый вариант)
15. обработать уведомление EN_CHANGE и просто менять содержимое вектора data

из общих дополнений:
1. используется двойная буферизация
2. отрисовка производится только той части таблицы, которая пересекает PAINTSTRUCT::rcPaint, т.е - минимум (кроме случая в пункте 7.3.)

матрицу значений data можно подменить с источника данных, в случае ODBC, т.е. вводим метод, к примеру: std::wstring Data(int y,int x), который будет обращаться к таблице на сервере (просто меняем на нее все вхождения data, их там немного)

вопросы пишите только в этой ветке, из PM буду гнать, поскольку каждому одно и то же объяснять не хочу
прикрепляю сам проект

Автор: GremlinProg 14.3.2009, 20:28
прикрепляю бинарник, чтобы по-быстрому посмотреть что получилось

перезалил, он требовал MSVCP90, теперь не требует, но весит, естественно, больше

ps: проект с дефолтными настройками, в нем я ни чего не менял, так что обращайте внимание на параметр "Incremental linking"

Автор: Dem_max 15.3.2009, 07:54
GremlinProg
Не запускается твой бинарник, сделай его со статичекой линковкой. А то хочиться посмотреть что у тебя получилось.

Автор: yngwie19 15.3.2009, 09:09
а у меня получилось запустить

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)