Inspired =)
  
Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005
Репутация: 13 Всего: 191
|
Итак, альфа версия контрола для собственного AutoComplete. Выполнен не в виде компонента (думаю, кому надо, тот исправит  ) Что есть: - Возможность управлять цветами выделения в списке;
- Отсутствие FocusRect'а у итемов;
- Вроде как полная эмуляция (две детали не учтено) навигации стандартного системного AutoComplete SysListView32;
- Windows XP Size Grip - однако с ним есть некоторые проблемы (при скроллинге).
Что надо доделать: - Сделать скроллинг (сейчас убран);
- Адаптировать для ComboBox;
- Сделать курсор в виде стрелочек у SizeGrip;
- Сделать навигацию еще более похожей на стандартную.
Как использовать: подключаем UACListBox.h к проекту, и можно создавать AutoComplete-списки со своим наполнением. Код *.h: | Код | //---------------------------------------------------------------------------
#ifndef UACListBoxH #define UACListBoxH //--------------------------------------------------------------------------- #endif
#include <StdCtrls.hpp> #include <Controls.hpp>
// Enhanced SizeGrip class TGrippie: public TObject { private: HWND Wnd; int FGripSize; public: __fastcall TGrippie::TGrippie(); virtual __fastcall ~TGrippie(void); // Apply the Grippie void __fastcall SetOwnerWindow(HWND Owner); __property HWND Handle = {read = Wnd, write = Wnd}; __property int GripSize = {read = FGripSize, write = FGripSize}; };
// AutoComplete ListBox (without FocusRect) - for internal use class TNoFRListBox: public TListBox { private: bool FChangeFlag; // Old Window Procedures TWndMethod OldBuddyWndProc; TWndMethod OldBuddyParentWndProc; // Old Buddy Text AnsiString OldBuddyText; // AutoComplete Items TStringList* FList; // SizeGrip TGrippie* FGrippie; // Buddy TWinControl* FBuddy; // Buddy Parent TWinControl* FBuddyParent; // Text color TColor FSelectedTextColor; // Item Color TColor FSelectedColor; // CN_DRAWITEM Message Callback void __fastcall OnDrawItem(TWMDrawItem &Msg); // WM_SIZE Message Callback void __fastcall OnWMSize(TWMSize &Msg); // OnMouseMove Handler void __fastcall ListMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); // OnClick Handler void __fastcall ListClick(TObject *Sender); protected: // Buddy WindowProc void __fastcall virtual BuddyWindowProc(TMessage &Msg); // Buddy Parent WindowProc void __fastcall virtual BuddyParentWindowProc(TMessage &Msg); void __fastcall SetSelectedTextColor(TColor Value); void __fastcall SetSelectedColor(TColor Value); void __fastcall CreateParams(Controls::TCreateParams &Params); public: BEGIN_MESSAGE_MAP // Drawing Handler MESSAGE_HANDLER(CN_DRAWITEM, TWMDrawItem, OnDrawItem); // WM_SIZE Handler MESSAGE_HANDLER(WM_SIZE, TWMSize, OnWMSize); END_MESSAGE_MAP(TListBox); // Constructor __fastcall TNoFRListBox::TNoFRListBox(TComponent* Owner); // Destructor virtual __fastcall ~TNoFRListBox(); void __fastcall ActivateResize(void); void __fastcall SetBuddyControl(TWinControl* Buddy); void __fastcall Add(AnsiString Item); __property TColor SelectedTextColor = {read = FSelectedTextColor, write = SetSelectedTextColor}; __property TColor SelectedColor = {read = FSelectedColor, write = SetSelectedColor}; };
|
Код *.cpp | Код | //---------------------------------------------------------------------------
#pragma hdrstop
#include "UACListBox.h" #include <uxtheme.h> #include <Themes.hpp> #include <vcl.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
#define SBP_SIZEBOX 10 #define SZB_RIGHTALIGN 1
// Grippie Window Procedure LRESULT APIENTRY GrippieWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { if (Msg == WM_PAINT) {
TPaintStruct PS; TRect Rect; GetClientRect(hWnd, &Rect); HDC DC = BeginPaint(hWnd, &PS); __try { if ((UseThemes) && (InitThemeLibrary)) {
HTHEME Theme = OpenThemeData(hWnd, L"SCROLLBAR"); if (Theme) {
__try { // "XP" SizeGrip DrawThemeBackground(Theme, DC, SBP_SIZEBOX, SZB_RIGHTALIGN, &Rect, NULL); } __finally { CloseThemeData(Theme); } } } // Theme API is unsupported by OS else DrawFrameControl(DC, &Rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
} __finally { EndPaint(hWnd, &PS); } return 0; } if (Msg == WM_ERASEBKGND) { return -1; } // Original Window Procedure return (CallWindowProc((FARPROC)GetWindowLong(hWnd, GWL_USERDATA), hWnd, Msg, wParam, lParam)); }
__fastcall TGrippie::TGrippie() { Wnd = 0; FGripSize = GetSystemMetrics(SM_CXHSCROLL); }
__fastcall TGrippie::~TGrippie(void) { DestroyWindow(Wnd); }
void __fastcall TGrippie::SetOwnerWindow(HWND Owner) { TRect Rect; ::GetClientRect(Owner, &Rect); Wnd = CreateWindowEx(0, "SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE | SBS_SIZEBOX, Rect.Right - FGripSize, Rect.Bottom - FGripSize, FGripSize, FGripSize, Owner, 0, GetModuleHandle(NULL), NULL); // Subclassing SetWindowLong(Wnd, GWL_USERDATA, SetWindowLong(Wnd, GWL_WNDPROC, (LONG)GrippieWndProc)); }
void __fastcall TNoFRListBox::OnDrawItem(TWMDrawItem &Msg) { Canvas->Handle = Msg.DrawItemStruct->hDC; Canvas->Font = Font; Canvas->Brush = Brush; if (Msg.DrawItemStruct->itemID == (UINT)-1) { Canvas->FillRect(Msg.DrawItemStruct->rcItem); return; } if (Msg.DrawItemStruct->itemState & ODS_SELECTED) { Canvas->Brush->Color = FSelectedColor; Canvas->Font->Color = FSelectedTextColor; } LongRec LR = {Msg.DrawItemStruct->itemState}; TOwnerDrawState State = (TOwnerDrawState)LR.Lo; DrawItem(Msg.DrawItemStruct->itemID, Msg.DrawItemStruct->rcItem, State); Canvas->Handle = 0; }
// WM_SIZE Message Callback void __fastcall TNoFRListBox::OnWMSize(TWMSize &Msg) { TRect Rect; TListBox::DefaultHandler(&Msg); ::GetClientRect(Handle, &Rect); SetWindowPos(FGrippie->Handle, 0, Rect.Right - FGrippie->GripSize + 1, Rect.Bottom - FGrippie->GripSize + 1, 0, 0, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE); }
// OnMouseMove Handler void __fastcall TNoFRListBox::ListMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { ItemIndex = SendMessage(Handle, LB_ITEMFROMPOINT, 0, (LPARAM)MAKELPARAM(X, Y)); }
// OnClick Handler void __fastcall TNoFRListBox::ListClick(TObject *Sender) { if (ItemIndex != - 1) { dynamic_cast<TEdit*>(FBuddy)->Text = Items->Strings[ItemIndex]; } Hide(); FBuddy->SetFocus(); dynamic_cast<TEdit*>(FBuddy)->SelStart = dynamic_cast<TEdit*>(FBuddy)->Text.Length(); }
void __fastcall TNoFRListBox::BuddyWindowProc(TMessage &Msg) { if (Msg.Msg == WM_KEYDOWN) { if (Visible) { switch (Msg.WParam) { case VK_UP: { FChangeFlag = false; if (ItemIndex == -1) { ItemIndex = Count - 1; } else ItemIndex--; if (ItemIndex == -1) { dynamic_cast<TEdit*>(FBuddy)->Text = OldBuddyText; } else { dynamic_cast<TEdit*>(FBuddy)->Text = Items->Strings[ItemIndex]; } dynamic_cast<TEdit*>(FBuddy)->SelStart = dynamic_cast<TEdit*>(FBuddy)->Text.Length(); FChangeFlag = true; return; } case VK_DOWN: { FChangeFlag = false; if (ItemIndex == Count - 1) { ItemIndex = -1; dynamic_cast<TEdit*>(FBuddy)->Text = OldBuddyText; } else { ItemIndex++; dynamic_cast<TEdit*>(FBuddy)->Text = Items->Strings[ItemIndex]; } dynamic_cast<TEdit*>(FBuddy)->SelStart = dynamic_cast<TEdit*>(FBuddy)->Text.Length(); SendMessage(FBuddy->Handle, EM_SETSEL, -1, 0); FChangeFlag = true; return; } case VK_RETURN: ListClick(NULL); } } } OldBuddyWndProc(Msg); }
// Buddy Parent WindowProc void __fastcall TNoFRListBox::BuddyParentWindowProc(TMessage &Msg) { if ((Msg.Msg == WM_COMMAND) && ((LPVOID)Msg.LParam == FBuddy->Handle)) { switch (Msg.WParamHi) { // Edit Text Has Changed case EN_CHANGE: { if (!FChangeFlag) return; OldBuddyText = dynamic_cast<TEdit*>(FBuddy)->Text; bool CompleteFlag = false; Left = FBuddy->Left; Top = FBuddy->BoundsRect.Top + FBuddy->Height; Clear(); int Len = OldBuddyText.Length(); for (int i = 0; i < FList->Count; i++) { if (FList->Strings[i].SubString(0, Len).UpperCase() == OldBuddyText.UpperCase()) { // Full String if (Len == FList->Strings[i].Length()) { CompleteFlag = true; break; } AddItem(FList->Strings[i], NULL); } } ((Count && Len && !CompleteFlag) ? Show() : Hide()); return; } // Edit Has Lost Its Focus case EN_KILLFOCUS: { Hide(); break; } } } OldBuddyParentWndProc(Msg); }
void __fastcall TNoFRListBox::SetSelectedTextColor(TColor Value) { if (Value != FSelectedTextColor) { FSelectedTextColor = Value; Invalidate(); } }
void __fastcall TNoFRListBox::SetSelectedColor(TColor Value) { if (Value != FSelectedColor) { FSelectedColor = Value; Invalidate(); } }
void __fastcall TNoFRListBox::CreateParams(Controls::TCreateParams &Params) { TListBox::CreateParams(Params); Params.Style = WS_CHILD| WS_CLIPSIBLINGS | WS_TABSTOP | LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT; }
__fastcall TNoFRListBox::TNoFRListBox(TComponent* Owner) : TListBox(Owner) { FChangeFlag = true; Visible = false; // Background Color Color = clBtnFace; Style = lbOwnerDrawFixed; OnMouseMove = ListMouseMove; OnClick = ListClick; // Set Constraints Constraints->MinHeight = 25; // SizeGrip FGrippie = new TGrippie(); // Items FList = new TStringList(); }
// Destructor __fastcall TNoFRListBox::~TNoFRListBox() { delete FGrippie; delete FList; }
void __fastcall TNoFRListBox::ActivateResize(void) { FGrippie->SetOwnerWindow(Handle); }
void __fastcall TNoFRListBox::SetBuddyControl(TWinControl* Buddy) { // Set Constraints Constraints->MinWidth = Buddy->Width; // Set Window Procedures OldBuddyWndProc = Buddy->WindowProc; FBuddy = Buddy; Buddy->WindowProc = BuddyWindowProc; // For Parent OldBuddyParentWndProc = Buddy->Parent->WindowProc; FBuddyParent = Buddy->Parent; Buddy->Parent->WindowProc = BuddyParentWindowProc; // Set Coordinates Left = FBuddy->Left; Top = FBuddy->Top + FBuddy->Height; }
void __fastcall TNoFRListBox::Add(AnsiString Item) { FList->Add(Item); }
|
Пример использования: | Код | //---------------------------------------------------------------------------
#include <vcl.h> #pragma hdrstop
#include "Unit1.h" #include "UACListBox.h" //---------------------------------------------------------------------------
#pragma comment(lib, "UxTheme.lib")
#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1;
//--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TNoFRListBox* FListBox = new TNoFRListBox(this); FListBox->Parent = this; FListBox->SelectedColor = clBlack; FListBox->SelectedTextColor = clWhite; FListBox->ItemHeight = 16; FListBox->Add("My computer"); FListBox->Add("Мои документы"); FListBox->Add("My documents"); FListBox->Add("Мой компьютер"); FListBox->Add("C:\\WINDOWS\\"); FListBox->Add("System"); // Edit, к которому прикручиваем автозаполнение FListBox->SetBuddyControl(Edit1); // Разрешаем изменение размеров списка FListBox->ActivateResize(); } //---------------------------------------------------------------------------
|
Это сообщение отредактировал(а) Rrader - 7.12.2008, 20:26
Присоединённый файл ( Кол-во скачиваний: 16 )
AutoComplete.rar 9,67 Kb
|