- This topic has 1 reply, 1 voice, and was last updated 16 years ago by Chike.
-
AuthorPosts
-
December 6, 2007 at 11:28 pm #191185ChikeMember
As a follow-up to problem locking the mic using code here is a code example of one way it can be done:
#include #include #include struct command { const char *text; // in: text to look for int code; // out: command number }; command my_commands[] = { { "lock mic", 0}, { "push to talk", 0}, { "console", 0}, { "send a file", 0}, { "all hands", 0}, { "view webcam", 0}, { "red dot", 0}, { NULL, 0} // stop when null }; struct fill_cmd_param { command *commands; int nfound; }; static void fill_commands(HMENU hMenu, fill_cmd_param *fcpp); int main(int argc, TCHAR* argv[]) { HWND hwnd = FindWindow("DlgGroupChat Window Class", NULL); if (hwnd == NULL) return 1; HMENU hmenu = GetMenu(hwnd); if (hmenu == NULL) return 2; fill_cmd_param fcp = {my_commands, 0}; fill_commands(hmenu, &fcp); if (fcp.nfound > 0) { printf("found %d commands:n", fcp.nfound); for (command *cmd = my_commands; cmd->text != NULL; ++cmd) { if (cmd->code != 0) { printf(" %s:t%dn", cmd->text, cmd->code); } else { printf(" %s:t(not found)n", cmd->text); } } } return 0; } // find substring sub in string str, case-insensitive static const char *strstri(const char *str, const char *sub) { size_t str_len = strlen(str); size_t sub_len = strlen(sub); if (sub_len > str_len) return NULL; const char *end = str + str_len - sub_len + 1; for (const char *s = str; s != end; ++s) { if (toupper(*s) == toupper(*sub) ) { const char *ssub = &sub[1]; for (const char *ss = &s[1]; *ssub && (toupper(*ss) == toupper(*ssub)); ++ss) ++ssub; if (*ssub == '�') return s; } } return NULL; } // walk through all menu items/sub menues and fill the static void fill_commands(HMENU hmenu, fill_cmd_param *fcpp) { if (hmenu == NULL) return; int nitems = GetMenuItemCount(hmenu); for (int i = 0; i < nitems; ++i) { UINT mstate = GetMenuState(hmenu, i, MF_BYPOSITION); if (mstate & MF_POPUP) { // search sub menu - recursive fill_commands(GetSubMenu(hmenu, i), fcpp); } else if (! (mstate & (MF_BITMAP | MF_OWNERDRAW))){ // imply MF_STRING char str[64]; if (GetMenuString(hmenu, i, str, sizeof(str), MF_BYPOSITION) > 0) { // match with one of our comma for (command *cmd = fcpp->commands; cmd->text != NULL; ++cmd) { if (strstri(str, cmd->text) != NULL) { // match // get menu cmd int code = GetMenuItemID(hmenu, i); if (cmd->code != 0) { // duplicate - which one to choose? fprintf(stderr, "%s: %d -> %dn", cmd->text, cmd->code, code); } else { cmd->code = code; ++fcpp->nfound; } break; } } } } } }
output:
found 6 commands:
lock mic: 33340
push to talk: 33343
console: 32998
send a file: 33231
all hands: 32995
view webcam: 33163
red dot: (not found)December 8, 2007 at 10:53 am #191186ChikeMemberOne problem with that code is that the room menues do not have all the commands you may want to look for.
So here’s a nother way to do it by reading the menu resources.
I excluded the some of the functions you can find in the 1st post.struct command { const char *text; int code; }; command my_commands[] = { { "lock mic", 0}, { "push to talk", 0}, { "console", 0}, { "send a file", 0}, { "all hands", 0}, { "view webcam", 0}, { "red dot", 0}, { "bounce", 0}, { NULL, 0} // stop when null }; static int find_commands(const char *fname, command *commands); int main(int argc, TCHAR* argv[]) { HWND hwnd = FindWindow("SEINFELD_SUPERMAN", NULL); if (hwnd == NULL) return 1; DWORD dwprocessid; // get process id - needed for OpenProcess if (GetWindowThreadProcessId(hwnd, &dwprocessid) == 0) return 2; HANDLE hprocess = OpenProcess( // access needed to enum and read resources PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, // don't care about handle inharitence FALSE, dwprocessid); if (hprocess == NULL) return 3; char fname[MAX_PATH]; // get paltalk process exectutable path int fnamelen = GetModuleFileNameEx(hprocess, NULL, fname, sizeof(fname)); if (fnamelen > 0) { int n = find_commands(fname, my_commands); if (n > 0) { printf("found %d commands:n", n); for (command *cmd = my_commands; cmd->text != NULL; ++cmd) { if (cmd->code != 0) { printf("t%s:t%dn", cmd->text, cmd->code); } else { printf("t%s:t(not found)n", cmd->text); } } } } CloseHandle(hprocess); return (fnamelen > 0) ? 0 : 4; } // doing it the easy way - too lazy to parse menu resource structure // loads each menu resource and send it to fill_commands static BOOL CALLBACK MyEnumResProc( HMODULE hmodule, LPCTSTR lpsztype, LPTSTR lpszname, LONG_PTR lparam) { if (lpsztype == RT_MENU) { // sanity HMENU hmenu = LoadMenu(hmodule, lpszname); if (hmenu != NULL) { fill_commands(hmenu, ((fill_cmd_param*)lparam)); DestroyMenu(hmenu); } } return TRUE; } static int find_commands(const char *fname, command *commands) { // load library as resource library without calling startup code HMODULE hmodule = LoadLibraryEx(fname, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hmodule != NULL) { fill_cmd_param fcp = {commands, 0}; // enumerate menu resources EnumResourceNames(hmodule, RT_MENU, MyEnumResProc, LONG_PTR(&fcp)); FreeLibrary(hmodule); return fcp.nfound; } return 0; }
output:
view webcam: 33163 -> 32905
send a file: 33231 -> 32902
push to talk: 33343 -> 33343
send a file: 33231 -> 33109
push to talk: 33343 -> 33338
lock mic: 33340 -> 33339
view webcam: 33163 -> 32905
send a file: 33231 -> 32902
view webcam: 33163 -> 32905
bounce: 32947 -> 32947
red dot: 32946 -> 32946
view webcam: 33163 -> 32905
send a file: 33231 -> 32902
found 8 commands:
lock mic: 33340
push to talk: 33343
console: 32998
send a file: 33231
all hands: 32995
view webcam: 33163
red dot: 32946
bounce: 32947There are some duplicates, part are the same codes, others differ.
I haven’t tested to see if all duplicates work or which does or doesn’t. -
AuthorPosts
- You must be logged in to reply to this topic.