firemail
标题: windows 覆盖图标实现 角标 [打印本页]
作者: Qter 时间: 2021-5-20 16:38
标题: windows 覆盖图标实现 角标
本帖最后由 Qter 于 2021-8-24 15:40 编辑
https://blog.csdn.net/lianjunming/article/details/102806525
文件文件夹图标 覆盖 实现
http://www.voidcn.com/article/p-hvrkzglq-tn.html
有两种开发方式,用C++ ATL开发需要手动在程序中编写相关的注册表,调试也有一些难度;用C#调SharpShell来实现会方便很多,且有相关的调试工具。
https://segmentfault.com/a/1190000009279826
https://blog.csdn.net/weixin_306 ... 1001.2101.3001.4242
注意点,前面多加空格 64位 32位分开- ForceRemove ' MyOverlayIcon' = s '{81539FE6-33C7-4CE7-90C7-1C7B8F2F2D40}'
复制代码 https://github.com/TortoiseGit/TortoiseGit
CloudDiskCornerMarker
overlayicon_src
https://www.codeproject.com/Arti ... sting-shell-objects
X64 Release版本编译自动注册成功
https://www.cnblogs.com/mq0036/p/14926674.html
https://docs.microsoft.com/en-us ... dlers-windows-shell
The number of icon overlay handlers that the system can support is limited by the amount of available space for icon overlays in the system image list. There are currently 15 slots allotted for icon overlays, 4 of which are reserved by the system. When there are more than 11 icon overlay handlers registered in the system, only the first 11 icon overlays that are provided by icon overlay handlers are added to the system image list. The remaining icon overlay handlers aren't used.
作者: Qter 时间: 2021-5-21 10:31
一般是由于 安装其他的 状态图标叠加程序导致的, 比如 微软的onedriver 或者 金山快盘 之类的工具, 可以把
注册表里面HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers
里面的除了 TortoiseSVN 之类的有关的可以删掉。
然后重启你的桌面。 就可以解决了。
转载于:https://my.oschina.net/zhuhj/blog/336020
作者: Qter 时间: 2021-7-22 14:40
使用ATL向导的话,会在resource中产生一个rgs的注册脚本文件放在"REGISTRY"目录中用来注册组件,会在程序中通过函数DECLARE_REGISTRY_RESOURCEID(IDR_OPCSERVER)使用,IDR_OPCSERVER就是向导产生的资源文件的ID,当服务器调用CComModule::RegisterServer()时,便会使用这些脚本来载入注册表的设置,并在调用CComModule::UnregisterServer()时移除它们。所有COM的注册键都放在HKEY_CLASSES_ROOT中。
https://blog.csdn.net/idiszerg/article/details/3875934
作者: Qter 时间: 2021-7-22 15:54
本帖最后由 Qter 于 2021-7-22 16:42 编辑
- STDMETHODIMP CShellExt::GetOverlayInfo(LPWSTR pwszIconFile, int cchMax, int* pIndex, DWORD* pdwFlags)
- {
- if (!pwszIconFile)
- return E_POINTER;
- if (!pIndex)
- return E_POINTER;
- if (!pdwFlags)
- return E_POINTER;
- if(cchMax < 1)
- return E_INVALIDARG;
- // Set "out parameters" since we return S_OK later.
- *pwszIconFile = 0;
- *pIndex = 0;
- *pdwFlags = 0;
- // Now here's where we can find out if due to lack of enough overlay
- // slots some of our overlays won't be shown.
- // To do that we have to mark every overlay handler that's successfully
- // loaded, so we can later check if some are missing
- switch (m_State)
- {
- case FileStateVersioned : g_normalovlloaded = true; break;
- case FileStateModified : g_modifiedovlloaded = true; break;
- case FileStateConflict : g_conflictedovlloaded = true; break;
- case FileStateDeleted : g_deletedovlloaded = true; break;
- case FileStateReadOnly : g_readonlyovlloaded = true; break;
- case FileStateLockedOverlay : g_lockedovlloaded = true; break;
- case FileStateAddedOverlay : g_addedovlloaded = true; break;
- case FileStateIgnoredOverlay : g_ignoredovlloaded = true; break;
- case FileStateUnversionedOverlay : g_unversionedovlloaded = true; break;
- }
- // we don't have to set the icon file and/or the index here:
- // the icons are handled by the TortoiseOverlays dll.
- return S_OK;
- };
复制代码 TortoiseGit-master\ext\TortoiseOverlays\readme.txt- The binary files in this directory are directly taken from the TortoiseSVN project.
- The source code and the original binary files are available in the TortoiseSVN Subversion repository:
- SourceForge Web-SVN-Browser: http://sourceforge.net/p/tortoisesvn/code/HEAD/tree/trunk/src/TortoiseOverlays/
- Official binaries: http://sourceforge.net/p/tortoisesvn/code/HEAD/tree/TortoiseOverlays/
复制代码 https://sourceforge.net/p/tortoisesvn/code/HEAD/tree/trunk/src/TortoiseOverlays/
C:\Program Files (x86)\Common Files\TortoiseOverlays\icons\
C:\Program Files\Common Files\TortoiseOverlays\icons
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\TortoiseOverlays\
然后根据这个 {3035134E-7B7D-4FCC-81B4-1E394CA267EB},会找到其实现的动态库TortoiseShell
TortoiseShell里面会再实现GetOverlayInfo函数
作者: Qter 时间: 2021-7-26 17:24
https://stackoverflow.com/questi ... ntifiergetoverlayin
https://stackoverflow.com/questi ... l/29791270#29791270
https://github.com/MicrosoftDocs ... overlay-handlers.md
https://www.programmersought.com/article/74726500719/
https://www.codeproject.com/Arti ... sting-shell-objects
https://www.codeproject.com/Arti ... riting-Shell-Extens
作者: Qter 时间: 2021-7-27 15:23
https://www.programmersought.com/article/74726500719/
IconOverlay implemented by Python, providing dynamic icon switching and refresh support
Development Platform- windows10
- python3.8
- pywin32
background knowledgeIcon overlay concept:Controversy over IconOverlay in Windows
Widows implementation:How to overlay an icon over existing shell objects
Python implementation:Add my own icon overlays
SHChangeNotify:SHChangeNotify
Problems with existing articlesinAdd my own icon overlaysThe author provides the code to implement the icon overlay function under python, but there are two problems
- Does not explain how to realize the judgment and reality of different overlay icons under different conditions when there are multiple icons
- There is no illustration on how to dynamically implement icon overlay switching and refreshing. For example, the icon overlay status in the current file explorer is in synchronization, how to use application code to control the icon overlay to the synchronization completion, and actively refresh the icon display in the user file resource browser Without requiring the user to manually refresh
solutionMultiple icon overlays to realize condition judgmentCreate multiple IconOverlay classes and register them at the same time, one IconOverlay class corresponds to one icon
Note that multiple IconOverlay classes must be differentreg_clsid Properties and thenGetOverlayInfo Different icons are returned in the method, and then inIsMemberOf The method returns whether to display the icon according to different conditions
My implementation is inIsMemberOf In the method, a file status table of the sqlite database is queried, and according to the file path in the table and the corresponding file status, it is determined which icon is displayed for the file
- import os
- import winreg
- import sqlite3
- import winerror
- import win32con
- // Pay attention to the import path here, the path of the old version of pywin32 is different
- from win32comext.shell import shell, shellcon
- class IconOverlayOk:
- """
- Icon overlay component
- The IShellIconOverlayIdentifier interface under the windows shell is used to implement the icon overlay function
- The following steps are required to implement functions in python
- 1. Use pywin32 to write python class to implement windows com components
- 2. Register the component to the windows system
- 3. Add the icon overlay component item in the registry
- 4. Restart explorer.exe
- When the windows file explorer browses the file
- 1. Explorer will call the IsMemberOf method of IShellIconOverlayIdentifier for each file currently to be displayed to determine whether the file needs to be processed
- 2. If IsMemberOf returns winerror.S_OK, the system will continue to call the GetOverlayInfo method to obtain the icon file to be superimposed
- 3. The operating system is responsible for superimposing the icon returned by GetOverlayInfo onto the original icon of the file
- _reg_remove_keys_: When uninstalling the component, the registry keys that need to be deleted at the same time. Here, add a space prefix to the last registry key name to ensure the priority of the icon overlay component and avoid other icon overlay programs such as oneDriver, Nut Cloud Unsuccessful competition causes the icon overlay to fail
- """
- _reg_clsid_ = '{EA258179-A91D-45F9-A237-FC92A5290423}'
- _reg_progid_ = 'SUN.PythonPackagesOverlayHandlerOK'
- _reg_desc_ = 'Icon Overlay Handler to indicate Python packages'
- _public_methods_ = ['GetOverlayInfo', 'GetPriority', 'IsMemberOf']
- _com_interfaces_ = [shell.IID_IShellIconOverlayIdentifier]
- _reg_remove_keys_ = [(r'Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ PyPackageOverlay1',
- win32con.HKEY_LOCAL_MACHINE)]
- def GetOverlayInfo(self):
- """
- Get the location of the icon file to be superimposed
- Obtain the icon file path iconPath from the registry
- :return:
- """
- key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'Software\Dachengyun')
- iconPath, index = winreg.QueryValueEx(key, 'iconPath')
- key.Close()
- return os.path.join(iconPath, 'Ok.ico'), 0, shellcon.ISIOI_ICONFILE
- def GetPriority(self):
- return 1
- def IsMemberOf(self, fname, attributes):
- """
- Determine whether to overwrite the file icon
- Read the synchronization folder path syncPath, sqlite database file path dbPath from the registry
- If the current file is under syncPath, go to db to query the file synchronization status
- Determine whether icon overlay is needed according to the file synchronization status
- :param fname:
- :param attributes:
- :return:
- """
- key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'Software\Dachengyun')
- syncPath, index = winreg.QueryValueEx(key, 'syncPath')
- dbPath, index = winreg.QueryValueEx(key, 'dbPath')
- key.Close()
- if fname.startswith(syncPath):
- filePath = fname[len(os.path.dirname(syncPath)):]
- conn = sqlite3.connect(dbPath)
- c = conn.cursor()
- c.execute('SELECT state FROM file_sync_state WHERE path=:filePath', {'filePath': filePath})
- r = c.fetchone()
- c.close()
- conn.close()
- if r is not None and r[0] == 1:
- return winerror.S_OK
- return winerror.E_FAIL
- class IconOverlaySync:
- _reg_clsid_ = '{EA258179-A92D-45F9-A237-FC92A5290423}'
- _reg_progid_ = 'SUN.PythonPackagesOverlayHandlerSync'
- _reg_desc_ = 'Icon Overlay Handler to indicate Python packages'
- _public_methods_ = ['GetOverlayInfo', 'GetPriority', 'IsMemberOf']
- _com_interfaces_ = [shell.IID_IShellIconOverlayIdentifier]
- _reg_remove_keys_ = [(r'Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ PyPackageOverlay2',
- win32con.HKEY_LOCAL_MACHINE)]
- def GetOverlayInfo(self):
- key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'Software\Dachengyun')
- iconPath, index = winreg.QueryValueEx(key, 'iconPath')
- key.Close()
- return os.path.join(iconPath, 'Sync.ico'), 0, shellcon.ISIOI_ICONFILE
- def GetPriority(self):
- return 2
- def IsMemberOf(self, fname, attributes):
- key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'Software\Dachengyun')
- syncPath, index = winreg.QueryValueEx(key, 'syncPath')
- dbPath, index = winreg.QueryValueEx(key, 'dbPath')
- key.Close()
- if fname.startswith(syncPath):
- filePath = fname[len(os.path.dirname(syncPath)):]
- conn = sqlite3.connect(dbPath)
- c = conn.cursor()
- c.execute('SELECT state FROM file_sync_state WHERE path=:filePath',
- {'filePath': filePath})
- r = c.fetchone()
- c.close()
- conn.close()
- if r is not None and r[0] == 2:
- return winerror.S_OK
- return winerror.E_FAIL
复制代码
Dynamic icon switching and refreshThe dynamic switching of icons only needs to modify the file status table data in the sqlite database in the external application code.
But this can only achieve the switching of icon overlays, not dynamic refresh; that is, when the user browses the file in the file explorer, if the current icon overlay file is being displayed, even if we re If the file status is changed in the database, the icon overlay will not be dynamically refreshed. You must manually refresh the file explorer or exit the folder and re-enter to see the changed overlay icon
The solution is to useSHChangeNotify To notify the operating system that the file has changed, so that the operating system does an active refresh
- // Pay attention to the introduction here, the introduction path of the old version of pywin32 seems to be different, which is prone to errors
- from win32comext.shell import shell, shellcon
- // syncPath is the absolute path of the file to be refreshed
- shell.SHChangeNotify(shellcon.SHCNE_ATTRIBUTES,
- shellcon.SHCNF_PATH | shellcon.SHCNF_FLUSHNOWAIT,
- bytes(syncPath, 'gbk'), None)
复制代码
Component registration uninstallation and explorer.exe restartAfter the IconOverlay class is written, it needs to be registered to the windows system. The code is as follows
- import os
- import win32api
- import win32con
- from win32com.server import register
- import iconOverlay
- // Multiple icons need to copy the following code, and register multiple classes after modifying the class name
- register.UseCommandLine(iconOverlay.IconOverlayOk)
- win32api.RegSetValue(win32api.RegCreateKey(iconOverlay.IconOverlayOk._reg_remove_keys_[0][1],iconOverlay.IconOverlayOk._reg_remove_keys_[0][0]),
- None, win32con.REG_SZ,
- iconOverlay.IconOverlayOk._reg_clsid_)
- register.UseCommandLine(iconOverlay.IconOverlaySync)
- win32api.RegSetValue(win32api.RegCreateKey(iconOverlay.IconOverlaySync._reg_remove_keys_[0][1],iconOverlay.IconOverlaySync._reg_remove_keys_[0][0]),
- None, win32con.REG_SZ,
- iconOverlay.IconOverlaySync._reg_clsid_)
- // Explorer needs to be restarted after component registration is complete.exe makes the component effective
- os.system('taskkill /f /im explorer.exe & start explorer.exe')
复制代码 Component uninstall
- import win32com.server.register
- win32com.server.register.UnregisterClasses(iconOverlay.IconOverlayOk)
- win32com.server.register.UnregisterClasses(iconOverlay.IconOverlaySync)
- os.system('taskkill /f /im explorer.exe & start explorer.exe')
复制代码
欢迎光临 firemail (http://firemail.wang:8088/) |
Powered by Discuz! X3 |