/* */ /* DESKICON.CPP by Andrew I. Reshin. Last modified 26.02.2001. */ /* */ #include #include #include // // Main dialog and it's controls // #define MAIN_DLG 10 #define IDC_STOP 20 #define IDC_COLOR 30 #define IDC_INSTALL 40 #define IDC_UNINSTALL 50 #define IDC_HOTTRACK 60 #define IDC_TWOCLICK 70 #define IDC_ULINEHOT 80 #define IDC_ULINECOLD 90 // // Create and show error message // #define _GETERR 0xFFFFFFFF /* ErrMsg must call GetLastError(). */ ULONG ErrMsg(HWND hParent,PCHAR sMsg,ULONG Code) { PCHAR usrmsg,buf,errmsg; if(Code==_GETERR) Code=GetLastError(); if(!sMsg) sMsg=""; buf=0; FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM, 0,Code,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(PCHAR)&buf,0,0 ); errmsg=(buf)?buf:"Unknown error\r\n"; usrmsg=(PCHAR)LocalAlloc(LMEM_FIXED,lstrlen(errmsg)+lstrlen(sMsg)+20); if(usrmsg) wsprintf(usrmsg,"%s\r\n[#%u] %s",sMsg,Code,errmsg); LocalFree(buf); MessageBox(hParent,usrmsg,0,MB_OK); LocalFree(usrmsg); return Code; } // // Create shortcut to the sFilePath at the sLnkPath // HRESULT CreateLink(PCHAR sFilePath,PCHAR sLnkPath) { WCHAR wpath[MAX_PATH]; IPersistFile *ppf; IShellLink *psl; HRESULT hres; if(FAILED(hres=CoInitialize(0))) return hres; hres= CoCreateInstance( CLSID_ShellLink,0,CLSCTX_INPROC_SERVER,IID_IShellLink,(PVOID*)&psl ); if(SUCCEEDED(hres)) { psl->SetPath(sFilePath); if(SUCCEEDED(hres=psl->QueryInterface(IID_IPersistFile,(PVOID*)&ppf))) { MultiByteToWideChar(CP_ACP,0,sLnkPath,-1,wpath,MAX_PATH); hres=ppf->Save(wpath,TRUE); ppf->Release(); } psl->Release(); } CoUninitialize(); return hres; } // // Search for user's StartUp folder // HRESULT GetStartupPath(HWND hParent,PCHAR sPath) { LPITEMIDLIST pidl; IMalloc *pimalloc; HRESULT hres; if(SUCCEEDED(hres=SHGetMalloc(&pimalloc))) { if(SUCCEEDED(hres=SHGetSpecialFolderLocation(0,CSIDL_STARTUP,&pidl))) { hres=SHGetPathFromIDList(pidl,sPath)?0:GetLastError(); pimalloc->Free(pidl); } pimalloc->Release(); } return hres; } // // Structure for EnumChildProc // typedef struct _ECP_DATA { OUT HWND hWnd; IN PCHAR sClass; } ECP_DATA, *PECP_DATA; // // EnumChildWindows callback. Find window by classname // BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam) { char name[32]; if(!GetClassName(hWnd,name,sizeof(name))) return TRUE; if(lstrcmpi(name,((PECP_DATA)lParam)->sClass)) return TRUE; ((PECP_DATA)lParam)->hWnd=hWnd; return FALSE; } // // Find desktop ListView32 window // HWND FindDesktop() { ECP_DATA ewd; HWND hwnd; if(hwnd=FindWindow("Progman","Program Manager")) { ewd.hWnd=0; ewd.sClass="SHELLDLL_DefView"; EnumChildWindows(hwnd,(WNDENUMPROC)EnumChildProc,(LPARAM)&ewd); if(hwnd=ewd.hWnd) { ewd.hWnd=0; ewd.sClass="SysListView32"; EnumChildWindows(hwnd,(WNDENUMPROC)EnumChildProc,(LPARAM)&ewd); hwnd=ewd.hWnd; }} return hwnd; } // // Path to .ini file // char IniPath[MAX_PATH]; // // As named.. // BOOL WritePrivateProfileInt(LPCTSTR sSec,LPCTSTR sKey,LONG Long) { char buf[16]; wsprintf(buf,"%d",Long); return WritePrivateProfileString(sSec,sKey,buf,IniPath); } // // Set text/background colors for desktop icons and ext.style for listview // #define _SMT(h,m,w,l,r) \ SendMessageTimeout((h),(m),(w),(l),SMTO_ABORTIFHUNG|SMTO_BLOCK,100,(r)) void SetDesktopIconSettings() { ULONG res,color,style; HWND hwnd; BOOL isok; if(!(hwnd=FindDesktop())) return; color=GetPrivateProfileInt("Options","Color",0,IniPath); isok=FALSE; if( _SMT(hwnd,LVM_GETTEXTCOLOR,0,0,&res) && res!=color && _SMT(hwnd,LVM_SETTEXTCOLOR,0,color,&res) ) isok=TRUE; if( _SMT(hwnd,LVM_GETTEXTBKCOLOR,0,0,&res) && res!=CLR_NONE && _SMT(hwnd,LVM_SETTEXTBKCOLOR,0,CLR_NONE,&res) ) isok=TRUE; if(isok) { InvalidateRect(hwnd,0,TRUE); UpdateWindow(hwnd); } if( (LONG)(style=GetPrivateProfileInt("Options","EStyle",-1,IniPath))!=-1 && _SMT(hwnd,LVM_GETEXTENDEDLISTVIEWSTYLE,0,0,&res) && res!=style ) _SMT( hwnd,LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRACKSELECT|LVS_EX_UNDERLINEHOT|LVS_EX_UNDERLINECOLD| LVS_EX_ONECLICKACTIVATE|LVS_EX_TWOCLICKACTIVATE, style,&res ); } // // Check AUTO3STATEs in the dialog box // void SetDlgState(HWND hParent) { ULONG style; HWND hwnd; if( (LONG)(style=GetPrivateProfileInt("Options","EStyle",-1,IniPath))==-1 && !((hwnd=FindDesktop()) && _SMT(hwnd,LVM_GETEXTENDEDLISTVIEWSTYLE,0,0,&style)) ) return; if(style & LVS_EX_TRACKSELECT) CheckDlgButton(hParent,IDC_HOTTRACK,BST_CHECKED); if(style & LVS_EX_UNDERLINEHOT) CheckDlgButton(hParent,IDC_ULINEHOT,BST_CHECKED); if(style & LVS_EX_UNDERLINECOLD) CheckDlgButton(hParent,IDC_ULINECOLD,BST_CHECKED); CheckDlgButton( hParent,IDC_TWOCLICK, (style & LVS_EX_ONECLICKACTIVATE)?BST_UNCHECKED: (style & LVS_EX_TWOCLICKACTIVATE)?BST_CHECKED: BST_INDETERMINATE ); } // // Set desktop's listview extended style // void SetDesktopExtStyle(HWND hParent) { ULONG style=0; UINT state; if(IsDlgButtonChecked(hParent,IDC_HOTTRACK)==BST_CHECKED) style |= LVS_EX_TRACKSELECT; if(IsDlgButtonChecked(hParent,IDC_ULINECOLD)==BST_CHECKED) style |= LVS_EX_UNDERLINECOLD; if(IsDlgButtonChecked(hParent,IDC_ULINEHOT)==BST_CHECKED) style |= LVS_EX_UNDERLINEHOT; state=IsDlgButtonChecked(hParent,IDC_TWOCLICK); if(state==BST_UNCHECKED) style |= LVS_EX_ONECLICKACTIVATE; if(state==BST_CHECKED) style |= LVS_EX_TWOCLICKACTIVATE; WritePrivateProfileInt("Options","EStyle",style); SetDesktopIconSettings(); } // // Choose new color and save values in .ini file // void SetColor(HWND hParent) { char i,key[16]="Custom"; ULONG cust[16]; for(i=0; i<16; i++) { key[6]='A'+i; cust[i]=GetPrivateProfileInt("Options",key,0,IniPath); } CHOOSECOLOR cc={ sizeof(CHOOSECOLOR), hParent,0, GetPrivateProfileInt("Options","Color",0,IniPath), cust,CC_RGBINIT,0,0,0 }; if(!ChooseColor(&cc)) return; WritePrivateProfileInt("Options","Color",cc.rgbResult); for(i=0; i<16; i++) { key[6]='A'+i; WritePrivateProfileInt("Options",key,cust[i]); } SetDesktopIconSettings(); } // // Create .lnk in StartUp folder // void Install(HWND hParent) { HRESULT hres; ULONG lnklen; PCHAR name,ext,bs; char exe[MAX_PATH],lnk[MAX_PATH],ch; if(FAILED(hres=GetStartupPath(hParent,lnk))) { ErrMsg(hParent,"Search for StartUp folder",hres); return; } lnklen=lstrlen(lnk); /* StartUp path is backslash terminated? */ bs=(lnk[lnklen-1]=='\\')?"":"\\"; /* Find full path of this app., filename and extension */ ext=exe+GetModuleFileName(0,exe,sizeof(exe)); for(name=ext; name>exe && *name!='\\' && *name!='.'; name--); if(*name=='.') ext=name; for(;name>exe && *name!='\\'; name--); if(*name=='\\') name++; if(sizeof(lnk) <= lnklen+(*bs?1:0)+ext-name+4) ErrMsg(hParent,"Create .lnk",ERROR_BUFFER_OVERFLOW); /* Build .lnk path and create .lnk file */ ch=*ext; *ext=0; wsprintf(lnk+lnklen,"%s%s.lnk",bs,name); *ext=ch; if(SUCCEEDED(hres=CreateLink(exe,lnk))) WritePrivateProfileString("Options","Startup",lnk,IniPath); else ErrMsg(hParent,"Create .lnk",hres); } // // Delete previously created .lnk and .ini // void Uninstall(HWND hParent) { char lnk[MAX_PATH]; if( GetPrivateProfileString("Options","Startup","",lnk,sizeof(lnk),IniPath) && !DeleteFile(lnk) ) ErrMsg(hParent,"Delete .lnk",_GETERR); if(!DeleteFile(IniPath)) ErrMsg(hParent,"Delete .ini",_GETERR); } // // Window procedure for dialog // BOOL CALLBACK DlgProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam) { if(Message==WM_INITDIALOG) { SetWindowLong(hWnd,GWL_USERDATA,lParam); SetDlgState(hWnd); } if(Message!=WM_COMMAND) return FALSE; switch(LOWORD(wParam)) { case IDCANCEL: EndDialog(hWnd,0); break; case IDC_STOP: SetEvent((HANDLE)GetWindowLong(hWnd,GWL_USERDATA)); EndDialog(hWnd,0); break; case IDC_COLOR: SetColor(hWnd); break; case IDC_HOTTRACK: case IDC_TWOCLICK: case IDC_ULINECOLD: case IDC_ULINEHOT: SetDesktopExtStyle(hWnd); break; case IDC_INSTALL: Install(hWnd); break; case IDC_UNINSTALL: Uninstall(hWnd); break; } return FALSE; } // // Entry point. // int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPrev,LPSTR sCmd,int nShow) { PCHAR ptr,endptr; HANDLE hevent; /* Find .ini path */ endptr=IniPath+GetModuleFileName(0,IniPath,MAX_PATH); for(ptr=endptr; ptr>IniPath && *ptr!='\\' && *ptr!='.'; ptr--); lstrcpy((*ptr=='.')?ptr:endptr,".ini"); /* If this app. is active show the configuration dialog */ if(hevent=OpenEvent(EVENT_ALL_ACCESS,FALSE,"DeskIconIsActive")) { DialogBoxParam(hInst,MAKEINTRESOURCE(MAIN_DLG),0,(DLGPROC)DlgProc,(LPARAM)hevent); CloseHandle(hevent); return 0; } /* Create event and set icon's text colors while it is not signaled */ hevent=CreateEvent(0,TRUE,FALSE,"DeskIconIsActive"); if(!hevent) return ErrMsg(0,"CreateEvent",_GETERR); do SetDesktopIconSettings(); while(WaitForSingleObject(hevent,2000)!=WAIT_OBJECT_0); CloseHandle(hevent); return 0; }