romka123
@romka123
Переучиваюсь из PHP в Java разраба

Есть ли библиотека на Go позволяющая добавить значок на панель задач Windows 10?

Добрый день! Есть ли библиотека на Go, позволяющая добавлять свой значок на панель задач Windows? Не путать с иконками, рядом с языком и часами. Для добавления иконки библиотека есть, я нашёл: github.com/getlantern/systray (классная и кроссплатформенная, но в винде добавляет значок в место №2, а мне бы хотелось добавить его в место №1 (см. скрин приложенный к вопросу). Если по каким то причинам такой библиотеки нет, буду благодарен за инфу как это сделать непосредственно через Win Api. Буду прям особенно благодарен, если получится привести примеры использования. Заранее спасибо!
6263fbf07b77a484321240.png
  • Вопрос задан
  • 784 просмотра
Решения вопроса 2
HemulGM
@HemulGM Куратор тега Windows
Delphi Developer, сис. админ
Это не значки и ни какое-то специальное винапи. Это просто встраивание окна в другое окно. Находят панель задач и устанавливают её родителем (SetParent) своего окна.
Ответ написан
Vindicar
@Vindicar
RTFM!
Роман Денискин, так, набросал пример на Питоне, так как Go не владею. Надеюсь, покажет, какие функции WinAPI использовать. Проблема в том, что твоё окно на панели задач придётся позиционировать вручную, а уж чтобы пользователь мог его таскать по панели задач... дикая морока.

Можно покопаться в COM-интерфейсах панели задач. DeskBands вроде ближе к твоим потребностям, но по-моему от них отказались.

код

# -*- coding: utf-8 -*-
import typing as t
import tkinter as tk
import ctypes
import ctypes.wintypes as w
 
def ErrorIfZero(result, func, args):
    if not result:
        raise ctypes.WinError(ctypes.get_last_error())
    return result
 
# используем user32.dll
user32 = ctypes.windll.user32
# описываем используемые функции, типы и константы 
WNDENUMPROC = ctypes.WINFUNCTYPE(w.BOOL, w.HWND, w.LPARAM)
 
user32.EnumWindows.argtypes = [WNDENUMPROC, w.LPARAM]
user32.EnumWindows.restype = w.BOOL
user32.GetClassNameW.argtypes = [w.HWND, w.LPWSTR, w.INT]
user32.GetClassNameW.restype = w.INT
user32.GetClassNameW.errcheck = ErrorIfZero
user32.GetWindowLongW.argtypes = [w.HWND, w.INT]
user32.GetWindowLongW.restype = w.DWORD
user32.SetWindowLongW.argtypes = [w.HWND, w.INT, w.LONG]
user32.SetWindowLongW.restype = w.DWORD
user32.SetWindowPos.argtypes = [w.HWND, w.HWND, w.INT, w.INT, w.INT, w.INT, w.UINT]
user32.SetWindowPos.restype = w.BOOL
user32.SetWindowPos.errcheck = ErrorIfZero
user32.SetParent.argtypes = [w.HWND, w.HWND]
user32.SetParent.restype = w.HWND
user32.GetParent.argtypes = [w.HWND]
user32.GetParent.restype = w.HWND
 
GWL_STYLE = w.INT(-16)
WS_CHILD = 0x40000000
SWP_NOACTIVATE = 0x0010
SWP_NOZORDER = 0x0004
SWP_SHOWWINDOW = 0x0040
 
 
# определяем дескриптор окна панели задач
def get_taskbar_window() -> w.HWND:
    class_buf = ctypes.create_unicode_buffer(256)
    handle: w.HWND = 0
    
    #callback - функция будет проверять каждое окно
    def process_window(hWnd: w.HWND, lParam: w.LPARAM) -> w.BOOL: 
        length = user32.GetClassNameW(hWnd, class_buf, len(class_buf))
        name = ''.join(class_buf[:length])
        if 'Shell_TrayWnd' == name: # имя класса окна панели задач всегда "Shell_TrayWnd"
            nonlocal handle
            handle = hWnd
            return 0 # нашли, стоп
        return 1 # не нашли, идём дальше
    # перебираем окна верхнего уровня
    user32.EnumWindows(WNDENUMPROC(process_window), 0)
    if handle == 0:
        raise ValueError('Taskbar not found')
    return handle
 
 
def make_attachment() -> tk.Tk: #создаём простое окно
    root = tk.Tk()
    
    def button_command():
        print('Bye!')
        root.destroy()
    
    item = tk.Button(root, text='Hello, World!', command=button_command)
    item.pack(expand=True, fill='both')
    return root
 
 
def attach(root: tk.Tk, hTaskbar: w.HWND):
    hTop: w.HWND = user32.GetParent(w.HWND(root.winfo_id())) #дескриптор окна верхнего уровня для нашего приложения
    user32.SetParent(hTop, hTaskbar) #задаём родителем панель задач
    user32.SetWindowLongW(hTop, GWL_STYLE, WS_CHILD) #говорим, что наше окно на самом деле дочернее, а не верхнего уровня
    user32.SetWindowPos(hTop, 
        0, #z-order - после какого окна должно идти наше. 0 - наверху
        500, 0, # положение окна, пикселей
        100, 40, # рамер окна, пикселей
        SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW) # позиционируем и показываем окно
 
 
hTaskbar = get_taskbar_window()
root = make_attachment()
# откладываем вызов attach(root, hTaskbar)
# так как ткинтер некоторые настройки задаёт не сразу же
root.after(1, attach, root, hTaskbar) 
root.mainloop()
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
tsklab
@tsklab
Здесь отвечаю на вопросы.
Go+WinAPI. Есть и библиотеки, и видео как использовать.
Руководство "Панель задач".
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы