DBGrid Фильтр по выделенному
Есть нужда в компоненте, более продвинутом чем DBGrid или как сделать на DBGrid аналог Access "фильтр по выделенному" где можно выделить часть текста в поле, нажать правую кнопку мыши и добавить *текст* (или %текст%) к имеющемуся фильтру
Делаешь контекстную менюшку на грид, и на пункт меню "фильтр по выделенному" вешаешь примерно такой код:
DBGrid1->SelectedField->FieldName + " = '"
+ DBGrid1->SelectedField->AsString
+ "'";
DBGrid1->DataSource->DataSet->Filtered = true;
боюсь что такой код выделит ВЕСЬ текст... Мне же нужно каким-то образом заставить DBGrid
1. реагировать на ПРАВУЮ кнопку мыши
2. получить из ячейки ВЫДЕЛЕННЫЙ текст
Если хочется создать видимость редактирования фильтра прямо в гриде, кидаешь на форму невидимый TEdit, перед фильтром позиционируешь его на ячейку грида, делаешь видимым, юзер редактирует значение, при выходе из TEdit делаешь фильтр примерно как у меня в коде, только со значением из Tedit.
Дя-я-я. Доку читать иногда полезно бывает.
"Кидаешь на форму невидимый TEdit"... А как, по-вашему, редакирование в гриде работает? Так и работает. А "невидимый TEdit" называется Inplace editor, и даже в свойствах где-то должен быть описан. С прорывки тоннеля в его сторону я бы и начал.
Дя-я-я. Доку читать иногда полезно бывает.
"Кидаешь на форму невидимый TEdit"... А как, по-вашему, редакирование в гриде работает? Так и работает. А "невидимый TEdit" называется Inplace editor, и даже в свойствах где-то должен быть описан. С прорывки тоннеля в его сторону я бы и начал.
Ну так начинай, а потом о результатах нам доложишь.
А если я хочу, например, в качестве editor'а ListView подцепить -- в DBGrid Inplace Listview есть?
... ну уж если без TEdit не обойтись, то как получить прямоугольник текущей ячейки грида?
Прямоугольник можно узнать в обработчике события OnDrawDataCell(TObject *Sender,
const TRect &Rect, TField *Field, TGridDrawState State) и запомнить до поры до времени где-нибудь, а потом, по событию соотв. пункта меню выводить Edit с нужными координатами.
Извини, пример делать времени нет, может, завтра.
у меня HELP на DBGrid показывает ошибку..
Inplace Editor не нашёл, но в документации к BC++ нашёл описание редактирования в ячейках, где говорится о том, что изменения пишутся в буфер, а когда перемещаемся на другую запись, постятся в базу... больше ничего...
боюсь что такой код выделит ВЕСЬ текст... Мне же нужно каким-то образом заставить DBGrid
1. реагировать на ПРАВУЮ кнопку мыши
2. получить из ячейки ВЫДЕЛЕННЫЙ текст
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Db.hpp>
#include <DBGrids.hpp>
#include <DBTables.hpp>
#include <Grids.hpp>
#include <Menus.hpp>
#include <ActnList.hpp>
#include <StdActns.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TTable *Table1;
TDataSource *DataSource1;
TDBGrid *DBGrid1;
TPopupMenu *PopupMenu1;
TMenuItem *Access1;
TMenuItem *N1;
TMenuItem *N2;
TMenuItem *N3;
TMenuItem *N4;
TMenuItem *N5;
TMenuItem *N6;
TMenuItem *N7;
TMenuItem *N8;
TMenuItem *Access2;
TActionList *ActionList1;
TEditCopy *EditCopy1;
TEditCut *EditCut1;
TEditDelete *EditDelete1;
TEditPaste *EditPaste1;
TEditSelectAll *EditSelectAll1;
TEditUndo *EditUndo1;
void __fastcall DBGrid1DrawDataCell(TObject *Sender, const TRect &Rect,
TField *Field, TGridDrawState State);
void __fastcall Access2Click(TObject *Sender);
private: // User declarations
TInplaceEdit* Editor_;
TWndMethod oldProc;
void __fastcall InplaceEditProc(TMessage& msg);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//in cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DBGrid1DrawDataCell(TObject *Sender,
const TRect &Rect, TField *Field, TGridDrawState State)
{
if (Editor_ == NULL)
{
if(DBGrid1->ControlCount == 1) {
Editor_ =static_cast<TInplaceEdit*>(DBGrid1->Controls[0]);
oldProc = Editor_->WindowProc;
Editor_->WindowProc = InplaceEditProc;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::InplaceEditProc(TMessage& msg)
{
if(msg.Msg == WM_CONTEXTMENU) {
PopupMenu1->Popup(msg.LParamLo, msg.LParamHi);
return;
}
oldProc(msg);
}
void __fastcall TForm1::Access2Click(TObject *Sender)
{
//Покажем, что тут...
ShowMessage(Editor_->SelText);
//а фильтр Drew поставит Сам
}
//---------------------------------------------------------------------------
Комментарии нужны?
где об этом всём можно прочесть?
у меня три гроссбуха (правда по 5 BCPP) но там этого нет... кстати и в HELP тоже :(
Комментарии ОЧЕНЬ нужны!!! :)
где об этом всём можно прочесть?
у меня три гроссбуха (правда по 5 BCPP) но там этого нет... кстати и в HELP тоже :(
Комментирую:
Мне же нужно каким-то образом заставить DBGrid1. 1. реагировать на ПРАВУЮ кнопку мыши
2. получить из ячейки ВЫДЕЛЕННЫЙ текст
Реагировать на правую кнопку мыши - контекстное меню. Это просто. Но тут второе желание -ВЫДЕЛЕННЫЙ ТЕКСТ.
Выделить текст в ячейке можно так:
При переходе DBGrid в режим редактирования она создает доп. контрол типа TDBGridInplaceEdit : public TInplaceEdit(то где ты вводишь текст). Который все сделает сам (организует выделение, покажет границы выделения и т.п.).
private: // User declarations
TInplaceEdit* Editor_;
...
(-) надо переводит в режим редактирования к тому же тут возникает проблема как присоединится к его меню. У меня за 20 минут это не получилось(может кто научит научит?). Поэтому ну его (ст. меню) на ХХХ, просто его заменим.
TPopupMenu *PopupMenu1;
TMenuItem *Access1;//доп. пункт
TMenuItem *N1; //сепаратор
TMenuItem *N2; //Выделить все
TMenuItem *N2; //сепаратор
TMenuItem *N2; //Удалить
... //и т.д.
чтобы не заморачиваться с обработкой Копи, Пасте и т.д. добавим TActionList и несколько ст. Action-ов и привяжем их к меню (св-во Action)
TActionList *ActionList1;
TEditCopy *EditCopy1;
TEditCut *EditCut1;
TEditDelete *EditDelete1;
TEditPaste *EditPaste1;
TEditSelectAll *EditSelectAll1;
TEditUndo *EditUndo1;
...
Теперь нужно наше меню посадить на InplaceEdit. Св-во PoupMenu у него недоступно, поэтому засабклассим его оконную процедуру и обработаем WM_CONTEXTMENU. Для этого осталось получить доступ к InplaceEdit. Как получить - тут все просто у каждого TControl есть св-во Controls. Где - я это сделал в DBGrid1DrawDataCell.
{
if(DBGrid1->ControlCount == 1) {
Editor_ =static_cast<TInplaceEdit*>(DBGrid1->Controls[0]);
oldProc = Editor_->WindowProc; //сабклассим
Editor_->WindowProc = InplaceEditProc;//его процедуру
}
}
//сама процедура...
void __fastcall TForm1::InplaceEditProc(TMessage& msg)
{
if(msg.Msg == WM_CONTEXTMENU) {//если WM_CONTEXTMENU, показываем наше меню
PopupMenu1->Popup(msg.LParamLo, msg.LParamHi);
return;
}
oldProc(msg);//иначе ...
}
Ну вот идея такая. Пробуй, Сам так ни разу не делал.
Можно было бы сделать и так: Родить свой редактор, наследоваться от TDBGrid и перекрыть UpdateEdit.
TCustomGrid::UpdateEdit()
{
if (CanEditShow())
{
if (FInplaceEdit == NULL)
{
FInplaceEdit = CreateEditor();//создать свой редактор
FInplaceEdit->SetGrid(this);
FInplaceEdit->Parent = this;
UpdateEditor();
}
else if (Col != FInplaceCol ||
Row != FInplaceRow)
{
HideEdit();
UpdateEditor();
}
// установить на место...
}
}
Где читать?
В Нелпе по Билдеру:
TControl::Controls, TControl::WindowProc.
TInplaceEdit,
TDBGridInplaceEdit//in dbgrids.pas.
TPopupMenu
TActionList
В Нелпе по WIN32:
WM_CONTEXTMENU
Got to known?
нет, комментарии не по коду :D :D
код я понял :D
по тому ГДЕ ПРОЧЕСТЬ?
Скажи, где почитать про такие штуки? Пожалуйста! ;) :D
Если знал бы где почитать думаешь стал бы Я код писать, а потом и комментировать? Поросто дал бы ссылку. Я же тебе говорю - родил за 20 минут. Все собрал из отдельных кусочков. Вообщем и целом такого нигде не видел. Надо знать св-ва и методы компонентов с которыми работаешь(Я тебе их перечислил). Ну если чего пиши.
Надо знать св-ва и методы компонентов с которыми работаешь(Я тебе их перечислил). Ну если чего пиши.
... это же свойства и методы только DBEdit... есть и другие компоненты...
ЯВНОГО описания или хотя бы перечисления в BC++ этих свойств нет... Ты-то их откуда-то взял...?
... это же свойства и методы только DBEdit... есть и другие компоненты...
ЯВНОГО описания или хотя бы перечисления в BC++ этих свойств нет... Ты-то их откуда-то взял...?
В Help-е. Иногда смотрю исходники VCL.
Просмотри всю иерархию от ... ну хотя бы TControl->TWinControl->...->TInplaceEdit. А вообще наврал маленько - была книжонка по Дельфе где расписывалась иерархия VCL, ее читал, но где и как называется не помню.
Ты, что студент что-ли?
Ты, что студент что-ли?
Студент :D Если бы :D
Можно было бы у кого-то спросить... самоучка...:(
потому и собираю где не попадя...
Но уж если наткнулся на знающего (без балды) человека, то уже спрошу: (тем более ты сам предлагал :)
Как в Win Media Player "вделана" в заголовок окна дополнительная кнопка? В АСЬКЕ такая же...
Как в Win Media Player "вделана" в заголовок окна дополнительная кнопка? В АСЬКЕ такая же...
Написанием собственных обработчиков сообщений WM_NCPAINT, WM_NCHITTEST и других из этой группы, отвечающих за работу неклиентской части окна.
ЯВНОГО описания или хотя бы перечисления в BC++ этих свойств нет... Ты-то их откуда-то взял...?
В $(BCB)\source\Vcl хранятся исходники всех стандартных компонентов, написанные на Дельфи. Читать бывает их очень полезно. Отмазки не принимаются:
- программистам, пишущим на Дельфи, надо знать Си, чтобы читать примеры MSDN
- программистам, пишущим на Билдере, надо знать Паскаль, чтобы читать исходники VCL
Паритет. ;)
К слову сказать, если нажать F1 и набрать в строке поиска "TInplaceEdit", вылезет достаточно скудное, но все-таки какое-никакое описание означенной темы.
RFTM. ;)
Студент :D Если бы :D
Можно было бы у кого-то спросить... самоучка...:(
потому и собираю где не попадя...
Но уж если наткнулся на знающего (без балды) человека, то уже спрошу: (тем более ты сам предлагал :)
Как в Win Media Player "вделана" в заголовок окна дополнительная кнопка? В АСЬКЕ такая же...
Ну один вариант тебе уже дали...
Можно еще попробовать так:
У формы - BorderStyle = bsNone
На форму панель
На панель сколько хочешь кнопок.
У панели:
TMouseButton Button, TShiftState Shift, int X, int Y)
{
long SC_DRAGMOVE = 0xF012;
if(Button == mbLeft)
{
ReleaseCapture();
SendMessage(this->Handle, WM_SYSCOMMAND, SC_DRAGMOVE, 0);
}
}
Размеры кнопок и панели получить через GetSystemMetrics(...)
напр.
Panel1->Height = GetSystemMetrics(SM_CYCAPTION);