Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.86/14: Рейтинг темы: голосов - 14, средняя оценка - 4.86
23 / 23 / 6
Регистрация: 16.10.2010
Сообщений: 211
1

PopupMenu исходный код

19.01.2012, 20:17. Просмотров 2930. Ответов 5
Метки нет (Все метки)

Не знаю возможно не туда пишу но тут роднее. Вот смотрел исходный код popupmenu так как нужно создать мне компонент что то среднее между этим меню и листбокс так вот суть проблемы. Я не могу понять на чем рисуется он, подозревая что на самом экране, и самая большая загадка где обрабатывается какой item выделен в данный момент.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.01.2012, 20:17
Ответы с готовыми решениями:

Исходный код rawToTIFF
есть у кого исходный код rawToTIFF

Как получить исходный код *.exe или отредактировать его исполняемый код?
Собственно возможно ли декомпилить его так, чтобы можно было потом обратно скомпилировать? Или...

Скрываем исходный код
Я делаю SDK, и я хочу скрыть код функционала, чтобы люди могли пользоваться только функциями. А...

Открыть исходный код exe
Доброго времени суток. Нужно срочно открыть исходный кoд exe'шника с пом. C++. Имею 2 среды...

5
LK
Заблокирован
19.01.2012, 20:42 2
Относительно "что то среднее между этим меню и листбокс"
Custom popup controls

by Damon Chandler

In this article, I’ll show you how to create a generic popup form, which can serve as the drop-down portion of a combo box or some other control. Figures A, B, and C depict some examples.

A combo tree-view control.
A combo list view control.
A combo color-picker control.


The ComboLBox class

The ComboLBox class is a native standard control class whose windows serve as the list box, or “drop-down”, portion of a standard style combo box. ComboLBox windows are similar to both child and top-level windows, but they are unique in two respects: First, they are children of the desktop window, which means that when a ComboLBox window is shown, its contents are not limited to the client area of a specific top-level window. If you’ve ever placed a combo box at the bottom of your form, you’ll recall that the drop-down portion can indeed exceed the bounds of the form (see Figure D). Second, unlike true top-level windows, a ComboLBox window can be displayed without forcing the active window to lose its active status. For example, instead of using a true combo box, you might be tempted to use an edit control, a button, and a small borderless form (for the drop-down portion). As depicted in Figure E, however, when you display another top-level window—borderless or not—the currently active window will lose activation.

A ComboLBox window can exceed the bounds of its associated form.

Mimicking a ComboLBox by displaying another top-level window will cause the main form to lose activation.

So, how does a ComboLBox window do it? How does it exceed the bounds of the form to which the combo box itself is parented without causing that form to lose activation? Well, as mentioned earlier, a ComboLBox window is a child of the desktop window. Because it’s a child of the desktop window, a ComboLBox window is not limited to the client area of a specific form. In a sense, all top-level windows are children of the desktop, but a ComboLBox window is a true child window—that is, it uses the WS_CHILD window style. It’s this window style that prevents the active window from losing activation when the ComboLBox window is displayed.

The TPopupForm class

The goal is to create a TForm descendant class that mimics the ComboLBox class. To do this, create a TForm descendant instead of a TListBox descendant. This is done for two reasons: first, a TForm descendant can be manipulated at design time; and second, because a TForm object is a container control (csAcceptsControls), other child controls can be placed within the form. This way, the drop-down window won’t be limited to just a list box. The declaration of this descendant class—which I’ll call TPopupForm—is provided in Listing A. I will provide a definition for each of its member functions in the following sections.

Specifying the window styles

The first task is to ensure that each TPopupForm window is created with the correct window styles; specifically those that are used by the ComboLBox class. To this end, you can override the CreateParams() member function and provide the following definition:
C++
1
2
3
4
5
6
7
8
9
void __fastcall TPopupForm::
  CreateParams(TCreateParams& Params)
 
  TForm::CreateParams(Params);
  Params.Style &=
    ~(WS_CAPTION | WS_SIZEBOX |
      WS_POPUP);
  Params.Style |= WS_CHILD | WS_BORDER;
  Params.ExStyle |= WS_EX_PALETTEWINDOW;
You may recall that the CreateParams() member function is an ideal place to manipulate the styles and extended styles that are later passed to the CreateWindowEx() API function. Because a drop-down window should not possess a title bar or a resizable border, the first step is to remove the WS_CAPTION and WS_SIZEBOX styles. The WS_POPUP style is also removed because this style cannot be used in combination with the WS_CHILD style. The WS_CHILD style is specified to make the form a true child window. The WS_BORDER style is set in order to achieve the thin-line border that’s inherent to ComboLBox windows. For the extended styles, the WS_EX_PALETTEWINDOW style is set. This serves two purposes. First, it makes the form top-most, which ensures that other windows won’t obscure the form. Second, it makes the form a tool window, which ensures that it won’t appear in the task list that is displayed when the Alt+Tab keystroke combination is pressed.

Specifying the parent window

As I mentioned earlier, the drop-down form needs to be a child of the desktop window so that the currently active form doesn’t lose its active status when the drop-down form is displayed. The WS_CHILD style has been specified, so now the parent window needs to be set. The SetParent() API function is used for this purpose. Call SetParent() and pass a handle to the desktop window (NULL) as the function’s second parameter. As its first parameter, the SetParent() function requires a handle to the window whose parent is to be changed (i.e., a handle to the drop-down form). The SetParent() function must be called after the TPopupForm window has been created. To this end, call the function from within an overridden CreateWnd() function, like so:
C++
1
2
3
4
5
void __fastcall TPopupForm::CreateWnd()
 
  TForm::CreateWnd();
  ::SetParent(
    Handle, GetDesktopWindow());
At this point, the drop-down form will appear as desired when it’s displayed, but it won’t behave like a true ComboLBox window. Specifically, steps must be taken to ensure that the drop-down form closes when the user clicks within its client area, and that it closes when the user dismisses it by clicking somewhere else. I will address the latter task first.

Handling the mouse messages

The task of closing the TPopupForm window is trivial—simply call the Close() function. The question is, when should this function be called (in response to what event)? Well, you could use the TPopupForm’s OnMouseDown event and then test the X and Y parameters to see if the user clicked outside of its client area:
C++
1
2
3
4
5
6
7
8
9
10
11
12
void __fastcall
TPopupForm::FormMouseDown(
  TObject *Sender, TMouseButton Button,
  TShiftState Shift, int X, int Y)
 
  // if the specified point is beyond
  // the bounds of the form...
  if (X < 0 || X >= Width ||
      Y < 0 || Y >= Height)
  
     // close the form
     Close();
The problem, however, is that the OnMouseDown event is typically fired only when the user has pressed a mouse button within the window’s client area. You need the OnMouseDown event to fire when the user presses a mouse button outside of the window’s client area. Fortunately, there’s an exception to the “within client area” rule. Specifically, the OnMouseDown event will be called—regardless of the position of the mouse cursor—if the popup window has captured the mouse. So, in order to ensure that the OnMouseDown event is invoked when the user presses the mouse button beyond the bounds of the drop-down form, use the SetCapture() API function to give the form mouse capture. This function must be called whenever the form is displayed (i.e., within the VisibleChanging() function), and whenever the mouse cursor leaves the bounds of the popup form (i.e., in response to the CM_MOUSELEAVE VCL message). Here’s the code:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void __fastcall
TPopupForm::VisibleChanging()
 
  TForm::VisibleChanging();
 
  // if the form is being hidden
  if (Visible)
  
    ReleaseCapture();
  
  // if the form is being shown
  else
  
    if (ActiveControl)
    
      SetCapture(ActiveControl->Handle);
    
    else SetCapture(Handle);
  
void __fastcall TPopupForm::
  CMMouseLeave(TMessage& AMsg)
 
  // when the cursor goes beyond the
  // bounds of our window, capture
  // the mouse...
  if (Visible)
  
    if (ActiveControl)
    
      SetCapture(
        ActiveControl->Handle);
    
    else SetCapture(Handle);
Notice the use of the ActiveControl property in both of these member functions; I’ll explain the logic behind this shortly. For now, focus on the call to the ReleaseCapture() API function from within the VisibleChanging() member function. The ReleaseCapture() function is called to restore the mouse capture whenever the form is being hidden. This function must also be called when the mouse cursor enters the bounds of the form so that child windows (of the drop-down form) can process mouse messages normally. This latter task is accomplished by using the CM_MOUSEENTER VCL message, as shown here:
C++
1
2
3
4
5
6
7
void __fastcall
TPopupForm::CMMouseEnter(TMessage& AMsg)
 
  // when the cursor is within the
  // bounds of our window, release
  // the mouse capture
  ReleaseCapture();
Handling the WM_ACTIVATEAPP message

There’s one final message that must be handled: WM_ACTIVATEAPP. This message is sent with a wParam set to false whenever the user activates another application. This provides a perfect opportunity to hide the drop-down form because it shouldn’t be lingering on top of the screen when the host application is not in the foreground. Here’s the code that goes within the WM_ACTIVATEAPP message handler:
C++
1
2
3
4
5
6
7
8
void __fastcall
TPopupForm::WMActivateApp(TMessage& AMsg)
 
  // if deactivating...
  if (!AMsg.WParam)
  
    // close the form
    Close();
That’s all there is to the TPopupForm class. Next I’ll show you how to put it to good use.

Using the TPopupForm class

After you’ve implemented the code for the TPopupForm class, the first thing you should do is add it to the Object Repository. This way, you can easily create descendant classes that you can manipulate at design time. The following sections take you through and example of creating such a descendant class, which I’ll call TTreeViewPopupForm.
Creating the TTreeViewPopupForm class

Because the TPopupForm class is in the Object Repository, creating a descendant class is trivial. Just choose “File | New...” from the main menu, select the parent class, choose the “Inherit” radio button, and then confirm the dialog (see Figure F).

Creating a TPopupForm descendant class by using the Object Repository.

At this point, you’ll be presented with a blank TPopupForm descendant window, which you can easily customize. (Remember, this design-time functionality was one of the main reasons the popup form is a TForm descendant. C++Builder 5 users may choose to use frames, if desired.) For this example, change the Name of the form to “TreeViewPopupForm”, and then add a TTreeView and a TImageList to it as depicted in Figure G.

A TPopupForm descendant class with a TTreeView object and a TImageList object.

There are three things that must be done to the TTreeViewPopupForm class before it’s useable. First, assign the tree-view’s OnMouseDown event handler to TPopupForm::FormMouseDown. Why is this assignment required? Well, recall from the TPopupForm::VisibleChanging() and CMMouseLeave() member functions that the SetCapture() function is called with ActiveControl->Handle if the form’s ActiveControl property is set. This way, mouse capture is given to ActiveControl (TreeView1 in the present example) instead of the form so that the active control can process mouse messages as it normally would. If mouse capture were given to the form (TreeViewPopupForm) instead of to the child window (TreeView1), the child window wouldn’t receive any mouse messages. In this example, this would prevent the tree-view’s nodes from being expanded. Because mouse capture is given to the active control instead of the drop-down form, it is necessary to ensure that the active control’s OnMouseDown event maps to the form’s OnMouseDown event. To accomplish this, the TPopupForm::FormMouseDown event is assigned to the OnMouseDown event of TreeView1. In conjunction with that, the next step is to set the ActiveControl property of the form to TreeView1. The third step is to provide a handler for the tree-view’s OnMouseUp event. This way, the drop-down form can be closed when the user selects a node. Here’s the code for that:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void __fastcall
TTreeViewPopupForm::TreeView1MouseUp(
  TObject *Sender, TMouseButton Button,
  TShiftState Shift, int X, int Y)
 
  // BCB4/5 users can alternatively use
  // the GetHitTestInfoAt function
  TV_HITTESTINFO tvhti = X, Y;
  SNDMSG(TreeView1->Handle, TVM_HITTEST,
    0,reinterpret_cast<LPARAM>(&tvhti));
 
  // if an item was hit...
  if (tvhti.flags & TVHT_ONITEM)
  
    // close the form
    Close();
Displaying the TreeViewPopupForm

To display the drop-down form, set its Top and Left properties (which are relative to the screen) and then simply call the Show() function:
C++
1
2
3
4
5
6
7
8
9
10
void __fastcall
TForm1::TreeViewButtonClick(
  TObject *Sender)
 
  RECT R;
  if (GetWindowRect(Edit1->Handle, &R))
  
    TreeViewPopupForm->Left = R.left;
    TreeViewPopupForm->Top = R.bottom;
    TreeViewPopupForm->Show();
You can show the drop-down window as part of a fake combo box (by using an edit/static control and a TSpeedButton), or perhaps in response to a click of the right mouse button. You can even use the drop-down form in conjunction with a toolbar to create a single-level “menu” such as the color box depicted in Figure C.

Conclusion

In the October 2000 issue, I showed you how to use the OnDrawCell event of the TStringGrid class to customize the appearance of a string grid. Well, now that you know how to display a generic drop-down form, you can use this method to efficiently display a combo box in each cell of a string grid. All you need to do is draw a drop-down button in each cell (by using the DrawFrameControl() API function), and then show the drop-down form (which contains, say, a TListBox) when this button is clicked.

There are a few limitations to using a drop-down form instead of a full-blown dialog. Namely, a drop-down form cannot receive keyboard focus without causing the main form to lose activation. For this reason, you should avoid using child windows that display a caret within your drop-down form. Just because a drop-down form cannot receive keyboard focus, doesn’t mean it can’t process keyboard messages. If you want to add keyboard navigation to the tree-view, for example, you can simply forward the WM_KEYDOWN/WM_KEYUP messages to the tree-view by using the SendMessage() API function. You can download a sample project that demonstrates this technique—along with the source code for the TPopupForm class—from www.residorph.com.

Listing A: The declaration of the TPopupForm class
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class TPopupForm : public TForm
 
__published:
  void __fastcall FormMouseDown(
    TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y);
 
protected:
  virtual void __fastcall CreateWnd();
  virtual void __fastcall CreateParams(
    TCreateParams& AParams);
  DYNAMIC void __fastcall VisibleChanging();
 
private:
  MESSAGE void __fastcall CMMouseEnter(
    TMessage& Msg);
  MESSAGE void __fastcall CMMouseLeave(
    TMessage& Msg);
  MESSAGE void __fastcall WMActivateApp(
    TMessage& AMsg);
 
public:
  __fastcall TPopupForm(TComponent* Owner);
 
BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(
    CM_MOUSEENTER, TMessage, CMMouseEnter)
  MESSAGE_HANDLER(
    CM_MOUSELEAVE, TMessage, CMMouseLeave)
  MESSAGE_HANDLER(
    WM_ACTIVATEAPP, TMessage, WMActivateApp)
END_MESSAGE_MAP(TForm)
;
Все остальное - как в "обычном" меню. Ну и, естественно, окно PopUpMenu "рисуется" на экране, как и все остальные окна.
2
23 / 23 / 6
Регистрация: 16.10.2010
Сообщений: 211
19.01.2012, 21:37  [ТС] 3
Ох. Я хотел разобратся как работает popupmenu эт понятно что на экране я думал что на форме какой то.
0
LK
Заблокирован
19.01.2012, 22:09 4
Leemurchonok, вы, видимо, не обратили внимание на
Все остальное - как в "обычном" меню.
Может, это будет для вас более авторитетным источником:
Контекстное всплывающее меню — компонент PopupMenu
В остальном работа с PopupMenu не отличается от работы с MainMenu.
0
23 / 23 / 6
Регистрация: 16.10.2010
Сообщений: 211
19.01.2012, 23:49  [ТС] 5
мечтал о таком. Наверное голова уже не варит. Не как не доходит как item получает фокус, ну знает что он выбран.

Добавлено через 2 минуты
Ладно на свежую голову завтра посмотрю. А вот еще какой момент где для функции CreateParams искать параметры формы?
0
LK
Заблокирован
19.01.2012, 23:59 6
CreateParams - класс (System.Windows.Forms)
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.01.2012, 23:59

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Исходный код лексического анализатора
Может есть у кого то исходник по ООП программы лексического анализатора Очень нужен пример ...

x86 интерпретатор исходный код
кто-нибудь слышал про интерпретаторы x86? в инете нарыл только что в qemu, bochs есть встроенные...

Переделать исходный код. Код в Паскале,а нужно сделать его в Фортране
{$S+,R+} program arab_to_roman; uses crt; var n : word; ch : char; procedure...

Как узнать исходный код метода из dll через код C#?
Как узнать исходный код метода из dll через код C#? помогите, пожалуйста!! :sorry:


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.