This free Windows utility is for users of iTunes who have a password-protected music source. Maybe you subscribe to a password-protected podcast. Maybe you store your itunes library on a password-protected http server. What happens is that you launch iTunes and it pops up a dialog for you to enter your login name and password. Even if you've clicked "remember", it STILL pops up the dialog.
This utility will automatically click OK on that password-dialog, so long as "remember" is checked.
The source code shows how to monitor for pop-up dialogs.
The program is very simple. Ten times a second it searches for the "iTunes" window using FindWindow. If this is present, it also searches for any "Connect to..." dialogs that share the iTunes process id. It uses FindWindowEx to check that all the fields of that connect-to dialog are populated. If they are, it clicks OK.
It keeps a global counter called "hits", which says how many times it has clicked OK on one of those connect-to dialog boxes. iTunes will display up to three dialogs at once, so this utility will click up to three times. Any more times than that means that the password wasn't accepted: so, don't do any more clicking. (We reset the global counter when the iTunes application itself is terminated.)
There's on irritation to deal with: if explorer should crash and you restart it, then the taskbar will decide to show its WS_EX_TOOLWINDOW windows -- even though WS_EX_TOOLWINDOW is supposed to keep a window off the taskbar. Anyway, once every two seconds, we re-assert that we should be hidden off the taskbar just in case.
#include <windows.h> #include <map> #include <string> using namespace std; HWND hitunes=0; map<wstring,int> hits; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: { SetTimer(hwnd,1,100,0); SetTimer(hwnd,2,2000,0); return 0; } case WM_TIMER: { if (wParam==2) { // this little dance is in case explorer has crashed and rebooted. The rebooted // explorer would show us in the system tray. By doing this, we hide ourselves again. ShowWindow(hwnd,SW_HIDE); SetWindowLong(hwnd,GWL_EXSTYLE,WS_EX_TOOLWINDOW); ShowWindow(hwnd,SW_SHOW); return 0; } HWND hitunes = FindWindow(L"iTunes",L"iTunes"); if (hitunes==0) {hits.clear(); return 0;} DWORD itunesid; GetWindowThreadProcessId(hitunes,&itunesid); HWND hdialog=0; while (true) { hdialog=FindWindowEx(0,hdialog,(wchar_t*)32770,0); if (hdialog==0) break; DWORD dialogid; GetWindowThreadProcessId(hdialog,&dialogid); if (dialogid!=itunesid) continue; wchar_t c[100]; GetWindowText(hdialog,c,100); c[99]=0; if (wcsncmp(c,L"Connect",7)!=0) continue; wstring s=c; HWND hsyscredentials = FindWindowEx(hdialog,0,L"SysCredential",L""); if (hsyscredentials==0) continue; HWND hremember = FindWindowEx(hsyscredentials,0,L"BUTTON",L"&Remember my password"); if (hremember==0) continue; LRESULT check = SendMessage(hremember,BM_GETCHECK,0,0); if (check!=BST_CHECKED) continue; HWND huser = FindWindowEx(hsyscredentials,0,L"ComboBoxEx32",0); if (huser==0) continue; *c=0; SendMessage(huser,WM_GETTEXT,100,(LPARAM)c); if (*c==0) continue; HWND hpass = FindWindowEx(hsyscredentials,0,L"Edit",0); if (hpass==0) continue; LRESULT len = SendMessage(hpass,WM_GETTEXTLENGTH,0,0); if (len==0) continue; if (hits.find(s)==hits.end()) hits[s]=0; if (hits[s]>3) continue; hits[s] = hits[s]+1; SendMessage(hdialog,WM_COMMAND,IDOK,0); } return 0; } case WM_DESTROY: { KillTimer(hwnd,1); KillTimer(hwnd,2); PostQuitMessage(0); } } return DefWindowProc(hwnd, msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int) { HWND hold = FindWindow(L"iTunesPasswordClickerClass",L"iTunes Password Clicker"); if (hold!=0) SendMessage(hold,WM_CLOSE,0,0); // There's a race which would allow two instances of the password-clicker to be running // (to wit.: if both of them passed this first test, then continued on to each // create their windows). // That doesn't matter. Having two password-clicker windows is benign. WNDCLASSEX wcex; ZeroMemory(&wcex,sizeof(wcex)); wcex.cbSize=sizeof(WNDCLASSEX); wcex.lpfnWndProc=(WNDPROC)WndProc; wcex.hInstance=hInstance; wcex.lpszClassName=L"iTunesPasswordClickerClass"; RegisterClassEx(&wcex); CreateWindowEx(0x08000000,L"iTunesPasswordClickerClass", L"iTunes Password Clicker",WS_POPUP|WS_VISIBLE,0,0,0,0,0,0,hInstance,0); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg); DispatchMessage(&msg);} // MessageBeep(0); return (int)msg.wParam; }