Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание своего компонента, Нужна помощь 
:(
    Опции темы
Superklug
Дата 6.12.2008, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Так я и не смог использовать этот класс( Он написан для Visual...
Теперь пытаюсь доделать компонент, который предложил MoLeX. У меня несколько вопросов:
1) Как сделать так, чтобы всплывающий список пропадал так же как и обычное PopupMenu. Сейчас это происходит только в случае когда Edit теряет фокус...
2) Как добавить этому компоненту новое событие - выбор элемента из списка?

Повторюсь, я никогда не писал компоненты... Расчитываю на вашу помощь.
PM MAIL   Вверх
Superklug
Дата 6.12.2008, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Rrader, Не знаю как и благодарить...

Это сообщение отредактировал(а) Superklug - 6.12.2008, 19:36
PM MAIL   Вверх
Rrader
  Дата 7.12.2008, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 13
Всего: 191



Итак, альфа версия контрола для собственного AutoComplete. Выполнен не в виде компонента (думаю, кому надо, тот исправит smile ) Что есть:
  •  Возможность управлять цветами выделения в списке;
  •  Отсутствие 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


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Superklug
Дата 7.12.2008, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Rrader, спасибо за Вашу работу, но есть несколько недочетов(( Во-первых список не всплывает за пределы формы. Во-вторых он не пропадает при щелчке на форме (например), это происходит только при потере Edit-ом фокуса. Ну и, разумеется, скрол...
PM MAIL   Вверх
Rrader
  Дата 8.12.2008, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 13
Всего: 191



Superklug, время будет, поправлю


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Superklug
Дата 10.12.2008, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



 smile 
Итог: несколько наполовину работающих компонентов((
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0497 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.