2 คะแนน โดย kck4156 5 시간 전 | 2 ความคิดเห็น | แชร์ทาง WhatsApp

ผมเพิ่งเผยแพร่ไลบรารีที่สามารถฝัง UI ของแอปลงไปในแถบงาน (taskbar) ของ Windows 11 ได้โดยตรง ชื่อว่า Deskband11Lib และเมื่อติดตั้งผ่าน NuGet ก็สามารถทำให้แอป WinUI 3 หรือ WPF กลายเป็นวิดเจ็ตบนแถบงานได้

ผมจะเล่าต่อว่าทำไมถึงสร้างมันขึ้นมา มันทำงานอย่างไร และรวมถึงวิดเจ็ต PoC ที่ผมนำขึ้น Store จริงด้วย


เบื้องหลัง: deskband ที่หายไปใน Windows 11

จนถึง Windows 10 ยังมีฟีเจอร์ Deskbands ที่สามารถแสดงแถบเครื่องมือขนาดเล็กบนแถบงานได้ แต่พอมาเป็น Windows 11 ฟีเจอร์นี้ก็หายไปทั้งชุด สำหรับคนที่อยากมี “วิดเจ็ตเล็ก ๆ ที่ลอยอยู่ตลอดเวลา” อย่างตัวควบคุมมีเดีย, system monitor หรือ quick launch ไว้บนแถบงาน นี่ถือเป็นการเปลี่ยนแปลงที่น่าเสียดายไม่น้อย

แรงบันดาลใจ: Deskband11 ของ zadjii

เมื่อไม่นานมานี้ผมเห็น zadjii/Deskband11 บน GitHub แล้วรู้สึกว่าหลักการเข้าถึงปัญหานั้นยอดเยี่ยมมาก

วางหน้าต่าง WinUI 3 แบบโปร่งใสทับลงไปบนแถบงาน จากนั้นใช้ SetParent ทำให้หน้าต่างนั้นกลายเป็น child HWND ของแถบงาน แล้วกำหนด clip region ตามขนาดของคอนเทนต์ เพื่อให้มันดูเหมือนเป็นส่วนหนึ่งของแถบงาน

สุดท้ายแล้วมันก็ “เป็นแค่หน้าต่างที่ลอยอยู่บนแถบงาน” แต่ไอเดียนี้ฉลาดมาก อย่างไรก็ตาม โปรเจกต์ต้นฉบับเองก็ระบุไว้ว่าเป็น “โค้ดระดับแฮกกาธอน” และยังมีจุดที่ไม่พร้อมสำหรับการนำไปใช้ในผลิตภัณฑ์จริง

ผมเลยทำมันใหม่เป็นไลบรารี

เพราะรู้สึกว่าไอเดียนี้น่าเสียดายถ้าจะปล่อยผ่าน ผมจึงเขียนมันใหม่เป็นไลบรารีเพื่อให้ใคร ๆ ก็ใช้ได้ด้วยคำสั่ง dotnet add package เพียงบรรทัดเดียว

วิธีใช้ก็ง่ายมาก

สร้างหน้าต่าง WinUI 3 ขึ้นมาหนึ่งอัน แล้วส่งเข้า TaskbarContentHost ก็เสร็จแล้ว

var window = new MainWindow();  
var host = new TaskbarContentHost(window, rootElement, new TaskbarContentHostOptions  
{  
    PreferredWidth = 360,  
    PreferredHeight = 48  
});  
  
await host.AttachWhenLayoutReadyAsync();  
window.Activate();  

ฝั่ง WPF ก็มี API ที่แทบจะเหมือนกัน ไลบรารีจะจัดการให้เองทั้งการตรวจจับการจัดวางแถบงาน (ซ้าย/กลาง), การหลีกเลี่ยงการซ้อนทับกับปุ่ม Start และพื้นที่แจ้งเตือน, การกู้คืนเมื่อ Explorer รีสตาร์ต และแม้แต่แอนิเมชันตอนเลย์เอาต์เปลี่ยน


กว่าจะทำให้มันใช้งานได้จริงก็ใช้เวลาไม่น้อย

ตอนลองรันโค้ดต้นฉบับแบบตรง ๆ มันเปิดขึ้นมาได้ก็จริง แต่ตำแหน่งและขนาดของหน้าต่างกลับเพี้ยนไปหมด เนื่องจากต้นฉบับเป็นโค้ดที่เขียนตอนแฮกกาธอน ตอนแรกผมเองก็ไม่แน่ใจว่าเป็นเพราะ Windows 11 อัปเดตแล้วเปลี่ยน implementation ของแถบงาน หรือว่าโค้ดเดิมมีจุดคลาดเคลื่อนอยู่แล้วกันแน่ ซึ่งทั้งสองอย่างก็อาจเป็นสาเหตุได้ เลยไม่มีทางเลือกนอกจากค่อย ๆ แกะฝั่งแถบงานออกมาดูทีละส่วน แล้วตรวจสอบด้วยตัวเองว่าใน build ปัจจุบันมันถูกจับอย่างไรจริง ๆ นอกจากนี้ต้นฉบับยังไม่ได้คำนึงถึงกรณีที่ปุ่ม Start อยู่ตรงกลาง หรือองค์ประกอบอย่างปุ่ม Widgets เลย ทำให้ตอนทำเป็นไลบรารีต้องใส่ใจเรื่องเหล่านี้เพิ่มใหม่ทั้งหมด

ดังนั้นจากต้นฉบับ ผมอ้างอิงเพียงวิธีใช้ UI Automation และ Win32 API สำหรับจับขนาด/ตำแหน่งหน้าต่างเท่านั้น ส่วน logic ในการคำนวณพื้นที่ว่างนั้นผมเขียนใหม่ทั้งหมดตั้งแต่ต้น เพราะต้องอ่านตำแหน่งของปุ่ม Start, กลุ่มปุ่มแอปบนแถบงาน, ปุ่ม Widgets และพื้นที่แจ้งเตือน เพื่อหาพื้นที่ที่เหลืออยู่ และตำแหน่งของพื้นที่ว่างก็ยังเปลี่ยนไปตามการจัดวางแถบงานว่าชิดซ้ายหรืออยู่ตรงกลางอีกด้วย จึงต้องออกแบบส่วนนี้ขึ้นมาใหม่


ผมทำแอปจริงขึ้นมาหนึ่งตัวและนำขึ้น Store แล้ว: BarPlay

เพื่อเช็กว่าไลบรารีนี้ใช้งานได้จริงแค่ไหน ผมจึงสร้างแอปหนึ่งตัวด้วยมันแล้วนำขึ้น Microsoft Store ชื่อว่า BarPlay

มันเป็นวิดเจ็ตที่แสดงภาพปก, ชื่อเรื่อง และปุ่มควบคุมของมีเดียที่กำลังเล่นอยู่บนแถบงาน ใช้งานได้กับทุกแอปที่รองรับ Windows System Media Transport Controls (SMTC) เช่น Spotify, เบราว์เซอร์ และแอป YouTube PWA ผมคอมไพล์มันด้วย NativeAOT เพื่อลดเวลาเริ่มต้นและการใช้ทรัพยากรให้เหลือน้อยที่สุด

ลิงก์แอปบน Microsoft Store

ผมลองแนะนำให้คนรู้จักรอบตัวดูก่อนแล้ว และกระแสตอบรับก็ค่อนข้างดี


เอาไปใช้ทำอะไรได้บ้าง

คุณสามารถนำคอนเทนต์ที่สร้างด้วย WinUI 3 หรือ WPF ไปวางไว้ในตำแหน่งที่มองเห็นได้ตลอดเวลาโดยไม่ต้องเปิดหน้าต่างแยกต่างหาก จะใช้ทำตัวจับเวลา, ตัวควบคุมการเล่นมีเดีย (แบบ BarPlay), สถานะบิลด์หรือการแจ้งเตือนจาก CI, system monitor, quick launcher, ตัวสลับบัญชี หรือ indicator สำหรับการแจ้งเตือนก็ได้

เพราะสามารถนำคอนโทรลและสไตล์ของแอปตัวเองขึ้นไปใช้บนแถบงานได้โดยตรง ผมจึงคิดว่านี่น่าจะเป็นไลบรารี .NET แทบจะตัวเดียวที่ทำให้สร้างประสบการณ์แบบนี้ได้บน Windows 11 ซึ่ง deskband ได้หายไปแล้ว


รวมลิงก์

เป็นไลเซนส์ MIT และคุณสามารถเริ่มต้นได้ด้วยการคัดลอกโปรเจกต์ตัวอย่าง (Deskband11Lib.WinUI.Sample, Deskband11Lib.Wpf.Sample) ผมยินดีต้อนรับทั้ง feedback, issue และ PR และถ้าคุณสร้างวิดเจ็ตแถบงานที่น่าสนใจขึ้นมาได้ ก็อย่าลืมบอกกันด้วยนะครับ

2 ความคิดเห็น

 
turtlehwan 4 시간 전

โอ้ ไอเดียดีมากเลยนะ

 
kck4156 4 시간 전

ขอบคุณครับ! จริงๆ แล้วผมแค่ทำให้มันเป็นไลบรารีเท่านั้น แต่คิดว่าน่าจะเป็นเพราะไอเดียของคนที่ทำต้นฉบับไว้ก่อนด้วยครับ.. 555