Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

charlo

[Resolvido] Selecionar registro no DBGrid com o botão direito

Recommended Posts

Olá gente boa tarde.

 

Não sei se alguém poderia me ajudar.

 

Eu tenho um DBGrid e um popup menu para esse DBGrid, eu gostaria que quando o usuário clicasse com o botão direito do mouse em algum registro nesse DBGrid o mesmo fosse selecionado como se faz com o botão esquerdo do mouse e depois aparecesse o popup menu.

 

Ou seja, a mesma função, idêntica quando você clica com o botão direito do mouse no Windows explorer e o mesmo seleciona o arquivo clicado com o botão direito e aparace o popup menu.

 

Se alguém puder me ajudar eu agradeço.

 

Obrigado mais uma vez gente.

 

Abraços,

 

Charlo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas se clicar com o botão direito sobre um item do dbgrid ele não esta recebendo o foco?

 

Olá Marcio, obrigado por responder.

 

É assim, quando eu clico com o botão direito o registro que eu cliquei sim recebe o foco mas não fica como registro selecionado na tabela entende?

 

 

 

Eu acho que consegui a solução mas não estou sabendo usar esse código que encontrei. Alguém poderia me ajudar a usar esse código? Nesse caso eu tenho interceptar o tempo que se clica com o botão direito do mouse em um item na grid e o tempo em que vai aparecer o PopupMenu com o evento WM_RBUTTONDOWN. Mas não estou sabendo usar. abaixo está explicado muito bem, mas não estou sabendo usar esse evento.

 

Eu tenho que criar uma nova unit e salvar na pasta do meu projeto ou adaptar tudo isso que está abaixo no meu projeto?

 

Obrigado mais uma vez pessoal.

 

 

Add a New Event to a Component: Right-Click in a TDBGrid

Question:

I need to add a right-click event to a TDBGrid, but am at a loss as to how to accomplish it. I want to pop up a menu. Do you know how?

 

Answer:

Before I start into this, there is an easier way to handle a right-mouse click to pop up a menu of sorts: Drop a TPopupMenu on a form and set its AutoPopup to True, then set the DBGrid's PopupMenu property to the name of the TPopupMenu.

 

It's amazing how easy it is (at least in many cases) to add functionality to a component. Mouse clicks are problably the easiest to implement, because the message structure of the windows message is fairly simple -- it's only one parameter!

 

unit Extgrid;

 

 

 

interface

 

 

 

uses

 

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

 

Forms, Dialogs, Grids, DBGrids;

 

 

 

type

 

TExtDBGrid = class(TDBGrid)

 

private

 

{ Private declarations }

 

FOnRightClick : TNotifyEvent;

 

procedure WMRButtonDown(var Message : TWMRButtonDown); message

 

WM_RBUTTONDOWN;

 

protected

 

{ Protected declarations }

 

public

 

{ Public declarations }

 

published

 

{ Published declarations }

 

property OnRightClick: TNotifyEvent read FOnRightClick write FOnRightClick;

 

end;

 

 

 

procedure Register;

 

 

 

implementation

 

 

 

procedure TExtDBGrid.WMRButtonDown(var Message : TWMRButtonDown);

 

begin

 

inherited;

 

if Assigned(FOnRightClick) then

 

FOnRightClick(Self);

 

end;

 

 

 

procedure Register;

 

begin

 

RegisterComponents('Samples', [TExtDBGrid]);

 

end;

 

 

 

end.

 

 

 

 

Okay, what did we just do? First of all we defined an event handling procedure:

 

procedure WMRButtonDown(var Message : TWMRButtonDown); message WM_RBUTTONDOWN;

 

the message directive following the declaration tells the component to watch for the message WM_RBUTTONDOWN, which is the message for the right mouse button down. What we've done with this procedure is make the component look for this message. However, mere awareness isn't enough, by far! We have to add a property of type TNotifyEvent (which if you remember is the domain in which mouse clicks fall) so that users can add code to process it. So, in the published section of the unit, we added:

 

property OnRightClick: TNotifyEvent read FOnRightClick write FOnRightClick;

 

to assign the message to the component.

 

If you're familiar with writing components, you'll notice the difference in how message properties are handled as opposed to regular properties. Typically, when setting and getting property values you would use a Get or Set method or a direct read and write to the properties' fields. In essence, things happen in response to the change in state of the property. This appears to occur in the notation of the unit above, but there's actually a bit more going on. In fact, it's a bit backwards. The FOnRightClick is not really a variable, but rather a pointer to an event-handling procedure. Luckily we don't have to know the mechanics behind this, because the compiler will automatically do all the work for us in creating the handler's declaration. However, if we look at the WMRButtonDown procedure, we'll see that the variable is actually being used as a procedure call:

 

procedure TExtDBGrid.WMRButtonDown(var Message : TWMRButtonDown);

 

begin

 

inherited;

 

if Assigned(FOnRightClick) then

 

FOnRightClick(Self);

 

end;

 

 

 

 

As I mentioned above, message handling works sort of in reverse of regular property setting. Where with a regular property, the change in the state of the property causes some code to fire off with an event, it's a message-aware procedure that sits in memory that changes the state of the message property. To illustrate this, in the code example above, the WMRButtonDown procedure makes the component aware of the right-click. Whenever the message appears in the message queue, WMRButtonDown fires. When it fires, it in turn fires off the FOnRightClick procedure, which on the component would be the event handler OnRightClick.

 

Use this code as a basis for writing your own events. The online help under WinAPI help has excellent discussions of messages and how they interact with the system. In addition to this though, I strongly recommend getting a book on the Windows API and getting the Resource Kit and SDK to really get into event handling.

 

 

 

Abraços,

 

Charlo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Noite

Esse codigo que você postou acima é de um novo componente derivado do DbGrid. você o instalou?

você só consegue usar o novo evento ( WM_RBUTTONDOWN ) com ele instalado e usando o novo DbGrid que tem o evento ( neste caso TExtDBGrid) veja a procedure Register - > RegisterComponents('Samples', [TExtDBGrid]).

Nao analisei o post original.... apenas vi o codigo do componente.

Tente e post se tiver duvida q dai instalo...

T+

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Noite

Esse codigo que você postou acima é de um novo componente derivado do DbGrid. você o instalou?

você só consegue usar o novo evento ( WM_RBUTTONDOWN ) com ele instalado e usando o novo DbGrid que tem o evento ( neste caso TExtDBGrid) veja a procedure Register - > RegisterComponents('Samples', [TExtDBGrid]).

Nao analisei o post original.... apenas vi o codigo do componente.

Tente e post se tiver duvida q dai instalo...

T+

 

 

Olá brigina, obrigado por responder.

 

Então, realmente se trata de um novo componente, mas eu não sei instalar em meu projeto.

Será que para instalar é da mesma maneira quando a gente instala através do menu COMPONENT / INSTALL COMPONENT?

 

Obrigado mais uma vez brigina.

 

Abraços,

 

Charlo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia.

Sim, mesmo processo. O ideal é você fazer uma package nova com seus componentes. Nao esqueça de colocar o "path" do arquivo .DCU ->No D7 é Menu Tools -> Environment Options -> Library -> Em Library Path click no botao a direita com 3 pontinhos -> Vai aparecer logo abaixo uns botoes sendo 1 escrito ADD. Click nele e localize onde você guardou o arquivo DCU (depois da nova package compilada e instalada).

ou se você nao conseguir, coloque a .DCU na pasta do delphi LIB.

T+

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia.

Sim, mesmo processo. O ideal é você fazer uma package nova com seus componentes. Nao esqueça de colocar o "path" do arquivo .DCU ->No D7 é Menu Tools -> Environment Options -> Library -> Em Library Path click no botao a direita com 3 pontinhos -> Vai aparecer logo abaixo uns botoes sendo 1 escrito ADD. Click nele e localize onde você guardou o arquivo DCU (depois da nova package compilada e instalada).

ou se você nao conseguir, coloque a .DCU na pasta do delphi LIB.

T+

 

Obrigado mais uma brigina, realmente era isso, consegui instalar o componente, eu já tinha conseguido fazer uma rotina para selecionado um registro no DBGrid com o botao direito do mouse + popup. Assim que eu chegar em casa (estou no trabalho), eu posto a soluçao para isso se caso alguém precisar.

 

Um abraço,

 

Charlo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Bom dia.

Sim, mesmo processo. O ideal é você fazer uma package nova com seus componentes. Nao esqueça de colocar o "path" do arquivo .DCU ->No D7 é Menu Tools -> Environment Options -> Library -> Em Library Path click no botao a direita com 3 pontinhos -> Vai aparecer logo abaixo uns botoes sendo 1 escrito ADD. Click nele e localize onde você guardou o arquivo DCU (depois da nova package compilada e instalada).

ou se você nao conseguir, coloque a .DCU na pasta do delphi LIB.

T+

 

Obrigado mais uma brigina, realmente era isso, consegui instalar o componente, eu já tinha conseguido fazer uma rotina para selecionado um registro no DBGrid com o botao direito do mouse + popup. Assim que eu chegar em casa (estou no trabalho), eu posto a soluçao para isso se caso alguém precisar.

 

Um abraço,

 

Charlo.

 

 

Bem gente, aqui está a rotina que inventei para poder dar certo o que eu queria.

 

procedure TForm1.DBGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
vlLinha: Integer;
begin
  begin
    //Aqui verifico se o botão pressionado é o botão direito do mouse
    if Button = mbRight then
      begin
        //Aqui verifico se os registros selecionados são maiores que 1 (no caso de a opção Multiselect do DBGrid estiver em True)
        if DBGrid1.SelectedRows.Count > 1 then
          begin
            //Aqui verifico se o registro selecionado está em foco (esse é o tal do HighLigh)
            if DBGrid1.SelectedRows.CurrentRowSelected = True then
              begin
                //Se é verdade então o CheckBox1 será desmarcado
                CheckBox1.Checked := False;
              end
            else
              begin
                //Se é falso vai ser deselecionado...
                DBGrid1.UnSelectAllClick(DBGrid1.SelectedRows);
                  begin
                    //...e será feito uma varrida nos registros do DBGrid...
                    with DBGrid1.DataSource.DataSet do
                      begin
                        for vlLinha := 0 to RecordCount - 1 do
                          begin
                            //...e será selecionado somente aquele registro em que você apontou e clicou com o botão direito do mouse
                            DBGrid1.SelectedRows.CurrentRowSelected := True;
                          end;
                      end;
                  //Atualizo os registros selecionados do DBGrid
                  DBGrid1.SelectedRows.Refresh;
                  end;
              end;
          end
        else
          begin
            //Aqui começa a segunda parte da condição principal. Se for menor que 1 então o CheckBox1 será desmarcado e o DBGrid1 será todo deselecionado
            CheckBox1.Checked := False;
            DBGrid1.UnSelectAllClick(DBGrid1.SelectedRows);
              begin
                //Varro novamente os registros do DBGrid...
                with DBGrid1.DataSource.DataSet do
                  begin
                    for vlLinha := 0 to RecordCount - 1 do
                      begin
                        //...e será selecionado somente aquele registro em que você apontou e clicou com o botão direito do mouse
                        DBGrid1.SelectedRows.CurrentRowSelected := True;
                      end;
                  end;
              //Atualizo os registros selecionados do DBGrid
              DBGrid1.SelectedRows.Refresh;
              end;
          end;
      end;
  end;
end;

OBS.: Eu usei o componente SMDBGrid muito conhecido entre muitos (ele já vem com funções de SelectAll e UnselectAll). Notem também que tive que usar um CheckBox para poder ficar fazendo as verificações necessárias. E mais uma nota, o CheckBox1 deve ser iniciado com a opção Checked em True e não esqueçam de colocar um PopupMenu apontando para o DBGrid.

 

 

Eu programo só por distração, não sou nenhum profissional nem nada, adoro o Delphi e programo por prazer. Se a minha rotina falhar ou estiver em desacordo com no que diz respeito a estrutura ou "poderia ser feito com menos linhas de código de outra maneira" eu peço desculpas. A minha intenção foi apenas ajudar sobre um problema que eu estava tendo e só consegui fazer dessa maneira como descrevi.

 

Abraços,

 

Charlo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.