Direct Win32 API, หน้าต่างทรงประหลาด และเหตุผลที่สิ่งเหล่านั้นหายไปเกือบหมด
(warped3.substack.com)- แอป Windows สมัยใหม่ช้าลงและหนักขึ้นจากการ พึ่งพาเฟรมเวิร์กบนเว็บ ทำให้ อำนาจควบคุมในระดับระบบปฏิบัติการ แบบยุค Win32 หายไป
- Win32 API สามารถกำหนดรูปร่างหน้าต่างได้อย่างอิสระผ่าน message loop และออบเจ็กต์ HRGN และในอดีต ดีไซน์หน้าต่างที่ไม่เป็นมาตรฐาน เป็นเรื่องพบได้บ่อย
- เมื่อใช้บิตแมปและ เทคโนโลยี layered window ก็สามารถสร้าง หน้าต่างรูปทรงอิสระ ที่มีความโปร่งใสและแอนิเมชันได้
- แต่หน้าต่างแบบคัสตอมค่อย ๆ หายไป เพราะมี ความซับซ้อนที่ต้องลงมือทำฟังก์ชันพื้นฐานเองทั้งหมด และเพราะผู้ใช้ หันไปนิยมความเรียบง่าย มากขึ้น
- ถึงอย่างนั้น Win32 ก็ยังคงให้ อิสระในการควบคุมหน้าต่างและการทดลอง และยังรักษา ความเป็นไปได้ในการสร้างซอฟต์แวร์เดสก์ท็อปเชิงสร้างสรรค์ เอาไว้
ความจำเจของแอป Windows ยุคใหม่ และอิสรภาพที่สูญหายไปของ Win32
- ช่วงหลังมานี้ แอปเดสก์ท็อปบน Windows ส่วนใหญ่ทำงานอยู่บนตัวห่อเบราว์เซอร์อย่าง React, Electron, Tauri จนกลายเป็น โครงสร้างแบบเว็บที่ซับซ้อน ซึ่งช้าและใช้หน่วยความจำมากเกินไป
- แม้แต่แอปจดบันทึกธรรมดายังใช้หน่วยความจำ 50MB แต่ แอปที่ทำงานเหมือนกันซึ่งเขียนด้วย Win32 C ล้วน ๆ ใช้เพียง 1.8MB
- แม้บนฮาร์ดแวร์รุ่นใหม่ อัตราการใช้หน่วยความจำตอนบูต Windows 11 ก็ยังสูงถึง 77%
- ในอดีตที่ยังเขียนโปรแกรมด้วย Win32 API โดยตรง นักพัฒนามี อำนาจควบคุมในระดับระบบปฏิบัติการอย่างสมบูรณ์
- ตอนนั้นไม่ได้ถูกจำกัดอยู่แค่หน้าต่างสี่เหลี่ยม แต่สามารถสร้าง หน้าต่างรูปทรงนอกมาตรฐาน ได้อย่างอิสระ
- ในยุค Windows XP แอปหลายตัวรวมถึง Windows Media Player มีรูปลักษณ์ที่โดดเด่นไม่เหมือนใคร
หน้าต่าง ‘ทรงประหลาด’ ในอดีต
- ครั้งหนึ่งแอปบน Windows ถูกสร้างขึ้นในรูปทรงหลากหลายเพื่อแสดง อัตลักษณ์และความเป็นตัวเอง
- โปรแกรมเล่นสื่อถูกทำให้ดูเหมือนฮาร์ดแวร์ มาสคอตเดสก์ท็อปวิ่งไปมาบนหน้าจอ และแผงยูทิลิตีถูกออกแบบให้เหมือน แผงหน้าปัด ของเล่น หรือคอนโซลจากต่างดาว
- รูปร่างของหน้าต่างไม่จำเป็นต้องเป็นสี่เหลี่ยม และ เป้าหมายของ UI ในตอนนั้นโน้มเอียงไปทางความมีเอกลักษณ์มากกว่าความใช้งานง่าย
- เหตุผลที่รูปแบบเหล่านี้หายไปในวันนี้คือ โปรแกรมเมอร์ไม่ได้ควบคุมตัวหน้าต่างเองอีกต่อไป
- เฟรมเวิร์ก UI สมัยใหม่ส่วนใหญ่ซ่อนระบบปฏิบัติการไว้ ทำให้นักพัฒนาทำงานได้เพียงภายในพื้นที่สี่เหลี่ยมที่มีข้อจำกัด
โครงสร้างแบบ message ของ Win32 และการควบคุมหน้าต่าง
- หัวใจของการเขียนโปรแกรมแบบ Win32 คือ event message loop
- ลูปที่ประกอบด้วย
GetMessage,TranslateMessage,DispatchMessageเป็นพื้นฐานของการทำงานทั้งหมด - พฤติกรรมของหน้าต่างถูกกำหนดผ่านการจัดการข้อความอย่าง “WM_CREATE”, “WM_PAINT”, “WM_SIZE”, “WM_DESTROY” เป็นต้น
- ลูปที่ประกอบด้วย
- หากใช้ HRGN (Region Object) ก็สามารถเปลี่ยนรูปร่างหน้าต่างได้อย่างอิสระ
- เมื่อกำหนด region ให้หน้าต่างด้วย
SetWindowRgnจะมีเพียงบริเวณนั้นเท่านั้นที่ถูกมองว่าเป็นหน้าต่างจริง - ในโค้ดตัวอย่างใช้
CreateEllipticRgnเพื่อสร้างหน้าต่างทรงวงรี และ ทำฟังก์ชันลากหน้าต่างขึ้นมาเองในสภาพที่ไม่มีแถบชื่อหน้าต่าง - เมื่อเกิด “WM_LBUTTONDOWN” จะส่ง “WM_NCLBUTTONDOWN” พร้อม “HTCAPTION” เพื่อ เลียนแบบการย้ายหน้าต่าง
- เมื่อกำหนด region ให้หน้าต่างด้วย
- แบบนี้เองที่ทำให้เห็นว่า การสร้างรูปร่างนั้นง่าย แต่โจทย์สำคัญคือฟังก์ชันที่เฟรมหน้าต่างพื้นฐานเคยให้มาจะต้องทำเองทั้งหมด
หน้าต่างแบบบิตแมปและ layered window
- ตัวอย่าง “drivenbyimage/main.c” ใช้ ข้อมูลบิตแมปกำหนดรูปร่างหน้าต่าง
- โหลด “shape.bmp” แล้วตั้งค่าพิกเซลทั้งหมดที่ไม่ใช่ สีโปร่งใส (magenta) ให้เป็นพื้นที่ของหน้าต่าง
- บิตแมปทำหน้าที่พร้อมกันทั้งเป็น ภาพที่วาดบนหน้าจอ และเป็น รูปร่างจริงของหน้าต่าง
- แอปแนวสกินในอดีตจำนวนมากใช้วิธีนี้สร้างรูปร่างต่าง ๆ เช่น สุนัข ยานอวกาศ วิทยุ หรือใบหน้าตัวละคร
- แต่ region ที่สร้างจากบิตแมปมี ขอบแข็ง และไม่สามารถแสดงความโปร่งใสแบบกึ่งทึบได้
- หากต้องการขอบที่นุ่มนวลหรือแอนิเมชัน จำเป็นต้องใช้ layered window (WS_EX_LAYERED)
- ในตัวอย่าง “Animated/” จะอัปโหลด ภาพ 32 บิตที่มีช่องอัลฟาโปร่งใส ด้วย
UpdateLayeredWindow- ใช้ GDI+ วาดสไปรต์ชีตลงบนบิตแมปในหน่วยความจำและสลับเฟรม จากนั้นแสดงผลบนเดสก์ท็อป
- รูปร่างของหน้าต่างจึงไม่ได้ถูกตรึงตายตัว แต่ สภาพของพิกเซลในขณะนั้นเองคือรูปร่างของหน้าต่าง
- วิธีนี้รองรับ ความโปร่งใสที่นุ่มนวล การเปลี่ยนรูปทรงในแต่ละเฟรม และแอนิเมชันที่เป็นธรรมชาติ
ความยากของหน้าต่างแบบคัสตอมและการเปลี่ยนแปลงทางวัฒนธรรม
- หากสร้างหน้าต่างคัสตอมด้วย Win32 API จะต้อง จัดการรายละเอียดการทำงานทุกอย่างด้วยตัวเอง
- ทั้งการลาก การปรับขนาด การปิด การรับอินพุตจากคีย์บอร์ด การรองรับ DPI และ ฟังก์ชันต่าง ๆ ที่หน้าต่างมาตรฐานเคยจัดการให้อัตโนมัติ ล้วนต้องเขียนเอง
- การทำต้นแบบอาจง่าย แต่การขัดเกลาให้เป็นผลิตภัณฑ์ที่สมบูรณ์ต้องใช้ ต้นทุนและความพยายามสูงมาก
- ผู้ใช้เองก็เริ่มให้ความสำคัญกับ ความเสถียรและความเรียบง่าย มากกว่าการทดลองด้านภาพลักษณ์
- หน้าต่างนอกมาตรฐานมักถูกเชื่อมโยงกับ แอดแวร์ ทูลบาร์ และยูทิลิตีที่ไม่จำเป็น จนเกิดภาพลักษณ์เชิงลบ
- ผลลัพธ์คือ “หน้าต่างทรงประหลาด” ถูกมองว่าเป็น ของเล่นสนุก ๆ มากกว่าจะเป็นซอฟต์แวร์จริงจัง
ความเป็นไปได้และความหมายที่ยังคงอยู่ของ Win32
- ถึงอย่างนั้น Win32 ก็ยังมอบ การควบคุมโดยตรงและอิสระในการทดลอง อยู่เสมอ
- เพียงแค่มี message, handle และ API สำหรับการวาด ก็สามารถ ควบคุมหน้าต่างในระดับระบบปฏิบัติการ ได้
- แม้ในกรณีส่วนใหญ่หน้าต่างสี่เหลี่ยมจะสมเหตุสมผลกว่า แต่นี่ก็เตือนให้เห็นว่า รูปทรงนั้นเป็นเพียงทางเลือก ไม่ใช่ข้อบังคับ
- โค้ดตัวอย่างเปิดเผยไว้ใน GitHub repository WierdApps
- มีตัวอย่าง 3 แบบ ได้แก่ หน้าต่างทรงวงรี หน้าต่างแบบบิตแมป และมาสคอตแอนิเมชัน
- สิ่งนี้แสดงให้เห็นว่า Win32 ยังคงทำให้ การสร้างซอฟต์แวร์เดสก์ท็อปที่สร้างสรรค์และเน้นการทดลอง เป็นไปได้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
หวังว่าหน้าต่างทรงประหลาดจะไม่กลับมาอีก
แค่เพราะทำได้ ไม่ได้แปลว่าควรทำ
ทุกวันนี้แอปที่ทำด้วย browser wrapper อย่าง React, Electron, Tauri ดูคล้ายกันไปหมด เพราะไม่ได้ใช้ GUI framework ของ OS
ถ้าแอปแต่ละตัวใช้ วิดเจ็ตที่ไม่เป็นมาตรฐาน หรือใช้สีและรูปทรงของตัวเอง การเข้าถึงและการใช้งานก็พังหมด
น่าเสียดายที่ทุกวันนี้แอปที่ชอบเน้น “อัตลักษณ์” ส่วนใหญ่กลับเป็นพวก แผงควบคุมไดรเวอร์ ที่ผู้ผลิตฮาร์ดแวร์ยัดมาให้ และนั่นแหละคือ bloatware ที่ห่วยที่สุด
ฉันชอบ Win32 แต่ก็มองว่าวัฒนธรรมสกินประหลาดๆ ในอดีตเป็นลางบอกเหตุของแนวคิดแบบ “แบรนด์ = อัตลักษณ์” ในปัจจุบัน
และสุดท้ายมันก็นำไปสู่การระบาดของ Electron กับไลบรารีวิดเจ็ตที่ทำไม่เสร็จครึ่งๆ กลางๆ
ถ้าไม่ใช่แอปเฉพาะทางอย่าง Blender หรือ Ardour, GUI ที่มีเอกลักษณ์ก็ไม่ใช่เรื่องสำคัญลำดับแรก
OS ยุคนี้ไม่ได้ทำมาเพื่อคนใช้ทั่วไป แต่ทำมาเพื่อองค์กร ยุค Win3.1~XP ต่างหากที่เป็นยุคของ personal computing อย่างแท้จริง
ทุกวันนี้ แอปที่สร้างบน React ไม่มีความสอดคล้องทั้งกับ OS และระหว่างกันเอง
UI เปลี่ยนทุก 6 เดือนแต่ UX ไม่ดีขึ้นเลย การเข้าถึง (a11y) เหมือนถูกลืมไปแล้ว
เมื่อก่อนซอฟต์แวร์ถูกสร้างโดยคนจำนวนน้อยและดูแลให้เสถียรอยู่ได้นาน
ตอนนี้เปลี่ยนเป็นการทำซ้ำอย่างรวดเร็วและทีมขนาดใหญ่ และ flat design ก็เป็นผลลัพธ์ที่เหมาะกับสภาพแวดล้อมแบบนี้
Skeuomorphic design มีต้นทุนสูงเพราะต้องทำแอสเซ็ตใหม่อยู่เรื่อยๆ
สุดท้ายก็กลายเป็นยุคที่ ความเร็วและขนาด มาก่อน เหมือนเฟอร์นิเจอร์ประกอบแบนๆ เข้ามาแทนที่ เฟอร์นิเจอร์แกะสลักด้วยมือ
พอเข้าสู่ยุค HiDPI ก็ยิ่งยากที่จะวาด UI แบบกำหนดเป็นพิกเซลเหมือนเมื่อก่อน
สมัย Win95~XP สามารถ วาดลง front buffer โดยตรง ได้เลย จึงเร็วและใช้หน่วยความจำน้อย แต่ตอนนี้ต้องเก็บ backup buffer แยกให้แต่ละหน้าต่าง เลยกิน RAM มากขึ้น
พอเห็นประโยค “The point was usually not usability. It was identity.” ก็รู้สึกเหมือนเป็น ข้อความที่ LLM เขียน
ฉันเคยพัฒนาแอป Windows มาก่อน และพบว่า อินเทอร์เฟซ Win32 ควบคุมได้แค่ราว 90%
จำได้ว่าตอนพยายามเปลี่ยน color theme ต้อง เขียน MessageBox ขึ้นมาใหม่เอง
Notepad ที่เขียนด้วย Win32 C ล้วนๆ ใช้แค่ 1.8MB แต่โปรแกรมจดบันทึกสมัยนี้กิน 50MB
ขนาด GNU Emacs ยังใช้หน่วยความจำน้อยกว่า
ส่วน EDIT.EXE แบบ text mode ใช้แค่ 520KB เลยมีประสิทธิภาพกว่ามาก
เมื่อก่อนบน Mac มีแอปเขียนแผ่น CD ชื่อ Disco ซึ่งตอนกำลังเขียนแผ่นจะมี แอนิเมชันควันลอยขึ้นมาบนหน้าต่าง
Steve Jobs ยังเคยโชว์บนเวทีด้วยตัวเองและชอบมันมาก
ดีใจที่บทความพูดถึงเรื่อง desktop mascot ด้วย
ไม่นานมานี้ฉันดู วิดีโอ desktop pet ที่ทำด้วย Godot ซึ่งทำงานได้ข้ามแพลตฟอร์ม
แม้จะต้องลงมือเยอะอยู่บ้าง แต่ก็ไม่ได้ซับซ้อนระดับ Win32 และเป็นตัวเลือกที่ดีสำหรับ คนชอบ desktop pet