Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Использование DevExpress 2

Автор: afiget
Дата сообщения: 04.08.2008 08:05

Цитата:
Может кто подскажет как зафиксировать колонку в cxGrid1DBTableView1

Уже было. Только у Bands.
Автор: GorBunOFF
Дата сообщения: 04.08.2008 16:39
Здравствуйте !
Колонки в гриде создаются динамически:
TcxGridDBBandedColumn* AColumn = cxGridMainAreaView->CreateColumn();
Пытаюсь на каждую вновь созданную повесить свой обработчик события OnGetCellHint:
AColumn->OnGetCellHint = ColGetCellHint;
При компиляции выдается ошибка:
[Linker Error] Unresolved external 'Cxgridcustomtableview::TcxCustomGridTableItem::SetOnGetCellHint(__closure(*)(Cxgridcustomtableview::TcxCustomGridTableItem *, Cxgridcustomtableview::TcxCustomGridRecord *, Cxgridcustomtableview::TcxGridTableDataCellViewInfo *, const Types::TPoint&, ...' referenced from ...

Кто подскажет что делать ?
Автор: jicoff
Дата сообщения: 04.08.2008 19:01
GorBunOFF

Значит обработчик ColGetCellHint не соответствует событию. А компилятор не выдает ошибку?
Автор: afiget
Дата сообщения: 04.08.2008 19:51
GorBunOFF
Попробуйте явно привести AColumn к TcxCustomGridTableItem.
Автор: GorBunOFF
Дата сообщения: 05.08.2008 07:39
Компилятор ошибку не выдает. Обработчик полностью соответствует :
void __fastcall А::ColGetCellHint(
TcxCustomGridTableItem *Sender, TcxCustomGridRecord *ARecord,
TcxGridTableDataCellViewInfo *ACellViewInfo, const TPoint &AMousePos,
TCaption &AHintText, bool &AIsHintMultiLine, TRect &AHintTextRect)
{

}
Явно приводить уже пробовал. Помоему это внутренняя ошибка. Хотя кто знает ?
Если мы вешаем этот обработчик на колонку в режиме дизайна, то всё работает как нужно. Но динамически нет.

Я не очень силен в Паскале, но вот реализация обработчика:
TcxGridGetCellHintEvent = procedure(Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
ACellViewInfo: TcxGridTableDataCellViewInfo; const AMousePos: TPoint;
var AHintText: TCaption; var AIsHintMultiLine: Boolean; var AHintTextRect: TRect) of object;

Реализацию на С++ см. выше. На С++ AMousePos передается по ссылке, а в паскале нет. Но повторяю в Паскале шарю ошень слабо.
Автор: zver
Дата сообщения: 05.08.2008 12:23
jicoff
Спасибо за ответ.
Но почему-то у меня первым параметром с++ требует не TCanvas * a TMetaClass *
Я пытаюсь передать Sender->Painter->LookAndFeelPainter и получаю AV
((TcxOffice11LookAndFeelPainter *)Sender->Painter->LookAndFeelPainter)->DrawHeader
    (Sender->Painter->LookAndFeelPainter,
    ACanvas, AViewInfo->Bounds, AViewInfo->TextBounds, AViewInfo->Neighbors,
    cxBordersAll, cxbsNormal, taLeftJustify, vaTop,
    False, True, "", ACanvas->Font, clNone, Color);
Автор: jicoff
Дата сообщения: 05.08.2008 14:21
zver

Прощу прощения, ввел в заблуждение. После своего ответа сам попробовал, т.к. бывает необходимость и самому реализовывать подобные вещи.

Потратил много времени, благо оно было. Пришел к неутешительному результату. Даже асм код смотрел в отладчике, и делал аналогичную реализацию на нем же. Методы класса, полагаю, извращение Борладна, в спп стандарте скорее всего нет такого, хотя они не противоречат ему. Борланд придумал это в паскале и возложил на компилятор правильную работу с ними, а в спп не перенес его нормальную поддержку.

Так вот, DevExpress нигде не создают объекты типа TcxLookAndFeelPainter. В нем и во всех его наследниках есть только методы класса, а это означает, что для работы с ними достаточно получить ссылку на таблицу методов и смещение на конкретный метод при вызове, что и делает код: Sender.Painter.LookAndFeelPainter.DrawHeader. Правильнее было бы на спп так:

if(Sender->Painter->LookAndFeelPainter->ClassNameIs("TcxOffice11LookAndFeelPainter"))
{
TcxOffice11LookAndFeelPainter *plaf = new TcxOffice11LookAndFeelPainter;
plaf->DrawHeader(Sender->Painter->LookAndFeelPainter, ...
...
delete plaf;
}

но при этом регистр EAX дожен содержать указатель на метакласс, а он содержит указатель на объект, как и положено в спп, да и в паскале, если это не метод класса. В итоге получаем не правильно сгенерированный код на спп.

Полагаю, этого нельзя делать - ((TcxOffice11LookAndFeelPainter*)Sender->Painter->LookAndFeelPainter), т.к. указатель на метакласс (TcxOffice11LookAndFeelPainterClass) и на объект (TcxOffice11LookAndFeelPainter*) не одно и тоже.


P.S. К тому же при вызове метода класса запихивается лишнее значение в стэк и при возврате не очищается.
Автор: zver
Дата сообщения: 05.08.2008 14:43
jicoff
Да всё интересно и печально одновременно...
Выдержка с офф сайта:

Цитата:

Reactivated by MisterHoops at 06.09.2006 4:13:38

Article A615 calls the DrawHeaderPressed() and DrawHeader() methods but when I tried I couldn't avoid access violations.

Thanks, Simon

Processed (Answered) by Developer Express Team at 06.09.2006 11:26:01

Hi Simon,

We understand what you wish to achieve and should mention that it is impossible o use just the same approach as I have implemented in the Delphi project attached to article A615. The DrawHeader method is declared as a class procedure in our source code and there is a problem in calling class methods (static in C++) in C++Builder. Unfortunately, we have failed to find a solution to this problem and we have tried to do this multiple times.

Thanks,
Plato


Автор: X11
Дата сообщения: 05.08.2008 15:05
Как быть? Читал, что в x37 (в деффках) Нет скинов. Можно ли их будет их прошлой версии доставить?
Или лучше откатиться на x35? В x36 глюки с шедулером, даже если я его не использую.
Автор: jicoff
Дата сообщения: 05.08.2008 16:03
zver

Можно извернуться, если только один класс TcxOffice11LookAndFeelPainter используется - проще, а так для всех придется делать. Создать паскалевский модуль, описать наследника от этого класса, для всех методов класса создать копии, но уже нормальные методы, которые вызываю каждый свой прототип, приводить к наследнику в нужном месте и вызывать вновь созданные методы.

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

typedef TRect __fastcall (__closure *cfHeaderContentBounds)(TMetaClass* vmt, const TRect &ABounds, TcxBorders ABorders);
typedef TRect __fastcall (*HeaderContentBounds)(TMetaClass* _ax, TMetaClass* vmt, const TRect &ABounds, TcxBorders ABorders);
union
{
cfHeaderContentBounds pcf;
HeaderContentBounds pfn;
}
uni;

uni.pcf = (cfHeaderContentBounds)&plaf->HeaderContentBounds;
uni.pfn(vmtPainter, vmtPainter, R, AViewInfo->Borders);
Автор: X11
Дата сообщения: 05.08.2008 16:08
Короче в x37 тот же глюк с шедулером, что и в x36. Хотя я шедулер не использую.

Добавлено:
Откатился на майских девок, x36, советую не включать шедулер при установке.
Автор: zver
Дата сообщения: 05.08.2008 17:08

Код: if (Sender->Painter->LookAndFeelPainter->ClassNameIs("TcxOffice11LookAndFeelPainter"))
{
TMetaClass* vmtPainter=Sender->Painter->LookAndFeelPainter;
TRect R=AViewInfo->Bounds; //R.Right=R.Right-10;
/*typedef TRect __fastcall (__closure *cfHeaderContentBounds)(TMetaClass* vmt, const TRect &ABounds, TcxBorders ABorders);
    typedef TRect __fastcall (*HeaderContentBounds)(TMetaClass* _ax, TMetaClass* vmt, const TRect &ABounds, TcxBorders ABorders);
    union
    {
     cfHeaderContentBounds pcf;
     HeaderContentBounds pfn;
    }
    uni;
    TcxOffice11LookAndFeelPainter *plaf = new TcxOffice11LookAndFeelPainter;
    uni.pcf = (cfHeaderContentBounds)&plaf->HeaderContentBounds;
    uni.pfn(vmtPainter, vmtPainter, R, AViewInfo->Borders); */


typedef void __fastcall (__closure *cfDrawHeaderBorder)(TMetaClass* vmt, Cxgraphics::TcxCanvas* ACanvas, const Types::TRect &R, TcxNeighbors ANeighbors, Cxgraphics::TcxBorders ABorders);
typedef void __fastcall (*DrawHeaderBorder)(TMetaClass* _ax, TMetaClass* vmt, Cxgraphics::TcxCanvas* ACanvas, const Types::TRect &R, TcxNeighbors ANeighbors, Cxgraphics::TcxBorders ABorders);
union
    {
     cfDrawHeaderBorder pcf;
     DrawHeaderBorder pfn;
    }
    uni;
    TcxOffice11LookAndFeelPainter *plaf = new TcxOffice11LookAndFeelPainter;
    uni.pcf = (cfDrawHeaderBorder)&plaf->DrawHeaderBorder;
    uni.pfn(vmtPainter, vmtPainter, ACanvas, R, AViewInfo->Neighbors, AViewInfo->Borders);
Автор: GorBunOFF
Дата сообщения: 06.08.2008 07:49
Вобчем по поводу ошибки посоветовать нечего. Жаль.
Автор: Ziltoid
Дата сообщения: 06.08.2008 08:15
Народ, не подскажете, как можно решить такую проблемку...
Надо покрасить ячейки грида и дерева по условию. Понятно, что об этом говорили не раз и надо, как доктор прописал, мастерить стили и вешаться на OnGetContentStyle.

Традиционно решить можно так (утрированный примерчик):

if ANode.Values[<Индекс>] = <Значение> then
AStyle := cxStyle1 else
AStyle := cxStyle2;

Проблема в том, что настройки грида и дерева (имена полей, их тип, ширина и тд) берутся из настроечной базы (по сути метаданные) и все это добро создается на лету - и запрос к БД, и колонки. К тому же некоторые поля в запросе есть, но в гриде(дереве) не отображаются. Через это не факт еще, что поле, по значению которого надо красить ячейку(ячейки), есть в гриде(дереве) и проверять здесь надо значение поля в запросе.
Только при этом он как-то странно красит. Если фокуса на записи, ячейку(ячейки) которой надо, нет, то раскраски нет. Стоит переместить фокус на эту запись, как раскрашивается предыдущая, на которой стояли и текущая, которую надо было изначально раскрасить. Перемещаешься на другую запись, раскраска исчезает. А если сделаешь тупо, как в утрированном примерчике, все прекрасно красится. Почему так?

Код:
// ColorHandler - класс-менеджер для работы с цветовыми схемами (может быть, если в метаданных есть описание цветовых схем, а может и не быть)
if ColorHandler = nil then Exit;
// CSI - структура описывающая одну цветовую схему (условие раскраски, раскрашиваемые поля, индекс стиля в репозитории)
CSI := ColorHandler.GetColor(Q.Fields);
if CSI <> nil then
// Если условие (нужное поле в запросе Q равно значению, заданному в условии) выполнилось, в AStyle сунем стиль, найденный в репозитории по индексу (стили тоже
// создаются на лету)

AStyle := TcxStyle(Styles.Items[CSI^.StyleIndex]) else
AStyle := DefaultStyle;

Может, я что-то не так делаю?
Автор: XeoNu905097
Дата сообщения: 06.08.2008 08:36
1. при преходе с v28 на v37 добавилоось масса dxSkins... и увеличился модуль EXE в 2х.
как можно гарантированно убрать dxSkins из Units - добавляются при компиляции.
2. как можно в cxDBTreeList добавить фильтры (ангалогично cxGrid-у) или какой альтернативный компонент использовать ?
Автор: X11
Дата сообщения: 06.08.2008 08:43
XeoNu905097
уже обсуждали - никак, пока что единственный способ - не устанавливать скины

Добавлено:
Применяй к своему экзешнику упаковщики, например UPX или ASPack.
ASPack есть бесплатная редакция. Прекрасно упаковывает.
Автор: afiget
Дата сообщения: 06.08.2008 09:41

Цитата:
ASPack есть бесплатная редакция

Не нашел такой на сайте. Есть только ASPack Free Trial.
Автор: X11
Дата сообщения: 06.08.2008 10:47
Вот и используй, в триальной версии некоторые ограничения, как то несохранение параметров.

Добавлено:
Вот, погуглил
http://www.google.com/search?hl=ru&q=%D0%B1%D0%B5%D1%81%D0%BF%D0%BB%D0%B0%D1%82%D0%BD%D1%8B%D0%B9+%D1%83%D0%BF%D0%B0%D0%BA%D0%BE%D0%B2%D1%89%D0%B8%D0%BA+exe+%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=

Добавлено:
http://softsearch.ru/programs/44-094-exe-upakovschik-download.shtml

Добавлено:
http://www.wasm.ru/toollist.php?list=8
UPX бесплатный, но старые версии пакера неправильно упаковывают "совеременные" exe, проги после упаковки не запускаются или глючат

Добавлено:
и для UPX`а я где-то видел GUI интерфейс, хотя можно сделать bat`ничек с параметрами и кинуть в папку проекта

Добавлено:
Вопрос по удалению в цикле. Есть cxGrid, подключенный к датасету. Нужно пробежаться по гриду и удалить записи, удовлетвлряющие некоторым условиям? Как лучше это сделать?
Вот примерный код:

Код:

for i := dbgReklama.ViewData.RecordCount - 1 downto 0 do begin
with dbgReklama.ViewData.Records do begin
if Values[dbgReklamadatas.index] = '' then continue;
bRecordNOTDel := Values[.....;
if bRecordNOTDel then
continue
else
удаляем эту строку...

end;//with
end;//for


Автор: Darl
Дата сообщения: 06.08.2008 13:59
GorBunOFF

OnGetCellHint:
AColumn->OnGetCellHint = (TcxGridGetCellHintEvent)&ColGetCellHint;
Автор: X11
Дата сообщения: 06.08.2008 16:11
Народ, кто даст пример, как правильно удалять в цикле записи в сгруппированном гриде (TcxGridDBTableView)? Замучался уже. (
Автор: afiget
Дата сообщения: 06.08.2008 16:28
X11
Зачем удалять в гриде? Удаляй в датасете.
И почему бы тогда уже не удалять прямо на сервере простым запросом?

В крайнем случае, в цикле по датасету не переходишь на следующую запись, если удалил текущую (следующая после удаления станет текущей).
Автор: X11
Дата сообщения: 06.08.2008 16:30
в датасете-то легко, а я хочу в гриде ))))))))
настоящие герои всегда идут в обход (с) Бармалей

Добавлено:
Грид может быть отфильтрован. Я хочу дать пользователю возможность удалять записи из отфильтрованного набора данных

Добавлено:
Я, конечно, пока переделаю на работу с датасетом, но хотелось бы поиметь примерчик
Автор: jicoff
Дата сообщения: 06.08.2008 17:44
X11

Так проблема с удалением или получением списка записей в группе?

Добавлено:
Если нужно пройти по записям, то примерно так (выдрал из своего класса, поэтому привожу как есть):

конструктор
FGroups = FOwner->DataController->Groups;
if(FGroups->GroupingItemCount)
{
int FocusedRowIndex;

FocusedRowIndex = FOwner->Controller->FocusedRowIndex;
FDataGroupIndex = FGroups->DataGroupIndexByRowIndex[FocusedRowIndex];
}

получение количества записей
if(FGroups->GroupingItemCount)
return FGroups->ChildCount[FDataGroupIndex];
else
return FOwner->ViewData->RowCount;

получение записи по индексу
TcxCustomGridRecord *pgrr;

if( !Count)
return ...;

if(FGroups->GroupingItemCount)
{
RowIndex = FGroups->ChildRecordIndex[FDataGroupIndex][RowIndex];
RowIndex = FOwner->DataController->GetRowIndexByRecordIndex(RowIndex, false);
}
pgrr = FOwner->ViewData->Rows[RowIndex];


Автор: afiget
Дата сообщения: 06.08.2008 18:23

Цитата:
Грид может быть отфильтрован. Я хочу дать пользователю возможность удалять записи из отфильтрованного набора данных

Ну и что. Разве проблема получить ключ записи?
Автор: GorBunOFF
Дата сообщения: 07.08.2008 08:19
Darl
Спасибо за подсказку. Но тоже не работает
Автор: XeoNu905097
Дата сообщения: 07.08.2008 17:05
кто-нибудь подскажет по поводу фильтра в cxDBTreeList (ангалогично cxGrid-у) или какой альтернативный компонент использовать ?
Автор: jicoff
Дата сообщения: 07.08.2008 19:04
XeoNu905097

А что мешает воспользоваться компонентами TcxFilterControl или TcxDBFilterControl?
Автор: XeoNu905097
Дата сообщения: 08.08.2008 08:38
в принципе да,
нужны 'filter dropdowns' на заголовках колонок
Автор: jicoff
Дата сообщения: 08.08.2008 14:27
XeoNu905097

Даже если нет 'filter dropdowns' на заголовках колонок, можно реализовать с помощью меню.
Автор: abos
Дата сообщения: 13.08.2008 10:01
Подскажите, плз, в чем можеи быть проблема (может, кто сталкивался)...
при исрользовании ExpressSkins Library чекбоксы, кнопки и др. не прорисовываюься, а на их месте красные кресты? На другом компьютере все нормально.

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182

Предыдущая тема: Язык программирования на русском языке


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.