2010-12-26

How to downgrade from Firefox 3.6

Hôm nay thì thực sự là bực mình với thằng FF rồi, và vừa chuyển sang dùng Google Chrome với Safari thì mình sẽ downgrade nó xuống. Chẳng hạn chuyển xuống 3.5 hay 2.0 cũng được. Chỉ cần download version cũ về và install thì FF sẽ tự động downgrade.

+ Tất cả các release có thể tìm tại FTP server của FF chỉ cần chọn win32 (hay OS nào tương ứng) chọn ngôn ngữ tiếng Anh EN-GB.
+ Chọn version stable 3.5.7
+ Hoặc chọn 3.5.16 tại đây FF 3.5 old version

Install lại FireBug cho 3.5 https://addons.mozilla.org/en-US/firefox/addon/1843/versions/

2010-12-23

How to disable plugin-container.exe Firefox 3.6.4

Từ khi update lên Firefox 3.6 có cái plugin-container thì FF chạy như con rùa CPU chạy 1x% bó tay với nó luôn.
https://www.mozilla.com/en-US/firefox/3.6.4/releasenotes/  mô tả ngắn gọn về nó nghe hấp dẫn kinh khủng trong khi sự thật rất thê thảm. Thà crash thì restart lại còn hơn dùng cái đồ rubbish này.

Firefox 3.6.4 provides uninterrupted browsing for Windows and Linux users when there is a crash in the Adobe Flash, Apple Quicktime or Microsoft Silverlight plugins.
If a plugin crashes or freezes, it will not affect the rest of Firefox. You will be able to reload the page to restart the plugin and try again. 

Google 1 hồi cũng tìm ra các để turn off nó. Hôm trước chửi Skype có cái archive message ngu như thú thì hôm nay Skype cũng die luôn rồi. Hic toàn những upgrade dỏm.

Cách tắt plugin-container:

+ Gõ command about:config trong address bar
+ Double click 4 phần dom.ipc.plugins.enable.np như trong hình, để chuyển thành user set enabled là false.
dom.ipc.plugins.enable.npctrl.dll
dom.ipc.plugins.enable.npqtplugin.dll
dom.ipc.plugins.enable.nptest.dll
+ Restart FF


2010-12-01

Microsoft Visual Studio 2008 RC/RTM uninstall tool

Hôm nay cài lại Visual Studio, máy này đã cài SQL Server 2008 trước. Chạy installer thì hiện ra là maintenance mode và bị báo lỗi 'A problem has been encountered while loading the setup components. Canceling setup.' Nói chung là rất khó chịu và bực mình. Chắc chắn là củ chuối này đụng với cái gì đó đã cài trên máy. Search vòng vòng một hồi, thì có lẽ completely uninstall trước rồi cài lại chắc được.

Có một vài bài ở đây
Trên Stackoverflow
Microsoft Visual Studio 2008 RC/RTM uninstall tool
Uninstall Visual Studio (all versions)

Dùng tool để thực hiện uninstall Visual Studio 2008 trước link tại đây UninstallTool.exe

Cũng liên quan đến việc install, lần này là lỗi với installer của VS 2008 (khi Add/Remove components) với cùng cái thông báo củ chuối 'A problem has been encountered....' , thực hiện remove hết updates và hotfixes liên quan như KB971091 thì installer không bị lỗi nữa.

Sau khi change/remove thì nhớ update lại lên service pack 1 để cho VS 2008 bình thường lại. Nếu không update lại thì lỗi hay gặp là VS 2008 không kết nối được SQL 2008, với thông báo lỗi 'This server version is not supported.  Only servers up to Microsoft SQL Server 2005 are supported'. Thật là lòng vòng, vì vậy nếu dùng VS 2008 nhiều và dư ổ cứng thì download Service Pack 1 để sẵn đó khoảng 800MB VS 2008 Service Pack 1 ISO

2010-11-08

Embedding subtitles (srt) into video files (avi) with Aegisub and VirtualDubMod

Hôm nay tính copy film vào USB rồi test thử trên TV nhưng mà mở ra thì subtitle có chút xíu, khó đọc quá. Mấy lần có xem phim download ở krfilm, thấy nó bỏ subtitle vào file avi luôn, font lớn và màu cũng dễ đọc nên tìm cách làm thử. Cuối cùng cũng làm ok.

1> Mấy file download format mkv thì convert sang .avi hay .mp4 (XviD hay DivX codec, TV nó kêu support DivX)
2> Tạo file .ass Aegisub Advanced SubStation Alpha Subtitle File bằng Aegisub (v2.1.7 download tại đây) rồi embed vào avi bằng VirtualDubMod (v1.5.10.2 download tại đây)

Covert mkv sang .avi hay .mp4
Mình search ra rồi thử dùng thằng Xilisoft MKV Converter convert 1 file mkv sang .avi nhưng cắm USB vào TV (LG 37") nó không nhận kêu là invalid format. Mình check ra nó chỉ support DivX Home Theater v3.0 (720 x576), hình như mình convert > 720 nên nó không play được (check tại DivX OEM/ODM, expand ra rồi gõ model vào xem nó support cái gì). Xong rồi mình dùng thử Total Video Converter, convert sang .avi xem trên PC thì OK nhưng mà cắm qua TV thì chất lượng hơi ẹ bị vài vùng giật giật, file size thì lớn từ 300MB hơn lên đến trên 1GB. Vậy là 2 cái tool cũng khá nổi tiếng nhưng lại cho ra chất lượng không mong muốn. Mình phải tìm cái nào khả dĩ hơn chút xíu. XviD4PSP convert thì mịn hơn kích thước cũng nhỏ nhưng chắc sẽ test thử một vài chương trình khác như DivX Plus.

Tạo file .ass với Aegisub
Aegisub không hỗ trợ tất cả các format nên nếu nó không nhận được format thì convert sang format thông dụng .avi hay .mpeg. Nếu nó nhận được video thì thường cũng nhận audio. OK mở Aegisub lên.


Open file srt có sẵn, sau đó open audio file và video file tương ứng. Sau khi open xong Aegisub sẽ hiển thị tương tự hình dưới.


Vì chỉ cần tạo .ass file nên sẽ không nói về chức năng tạo sub của Aegisu, chọn Style Manager. Chọn Default style để edit hoặc New một style mới.

 Window thực hiện chỉnh style như sau, đặt tên cho style và thực hiện config

Mình hay config theo thông số trong hình, với màu subtitle trắng, viền đậm đổ bóng shadow màu đen.
Các thông số quan trọng như sau:
1: Tên style
2: Font
3: Size thường chỉnh 45 với font Times new Roman
4: Màu chính thường để màu trắng
5: Màu 2nd dùng khi tạo karaoke
6: Outline viền ngoài đang để màu xanh với độ trong suốt 50 (từ 0 đến 255) để làm nổi subtitle những đoạn nào quá sáng không nhìn rõ chữ (màu xanh ví dụ #1C2CEE)
7: Shadow để màu đen


Về vị trí và canh lề mình không quan tâm cứ để như trong hình.


8: Độ dày outline thường để1 hoặc 2
9: Độ dày shadow để 1
10: Cho trong suốt nên không check opaque


Sau khi thực hiện xong và chọn đặt tên style, giả sử đặt tên thêm vào style name là blue để biết màu của style, chọn copy to current script, thoát ra màn hình chính.

Chọn một line trong phần subtitle rồi nhấn Ctrl + A để select all, sau đó chỉnh style cho toàn bộ bằng cách chọn style đã tạo. Xem lại kết quả.

Có thể tạo thêm vài style khác để xem cái nào hợp nhất, giả sử thêm style màu vàng như #FFEE55
Nếu xem thấy ưng ý vậy là đã có file ass, save file (Ctrl + S) vừa mới tạo. Xong qua tiếp bước embed ass vào avi file.


Embed ass file vào avi dùng VirtualDubMod
Mở VirtualDubMod


Open avi file, khi hiện dialog thì chọn No


Vào Video -> Filters (Ctrl + F) -> Chọn Add ... chọn tiếp TextSub và select file ass vừa mới tạo.


Đến bước này có thể thực hiện save avi mới với ass sub, tuy nhiên cần config nếu không thì output file sẽ có kích thước "khổng lồ". Vào Video -> Compression (Ctrl + P) -> Chọn Xvid MPEG-4 Codec và thực hiện chọn config

Tới đây nhấn config Xvid, nhiều thông số nhưng dơn giản thì chọn level là DivX Home Theater 720 x 576 mà mình đã đề cập ở trên, còn muốn thì chọn option nào phù hợp là được. Phần Target bitrate (kbps) để khoảng 900 hay 1000 gì đó, không thì chọn nút calc ... sẽ hiện dialog tiếp theo
 Trong dialog này chọn target size khoảng 600-700MB và chỉnh frames per second. Sau khi chỉnh xong thì nó sẽ tính bitrate cho mình.

Xong xuôi thực hiện save lại (Ctrl + S). Tắt 2 check option show input/output video cho nhẹ máy rồi ngồi đợi hay uống nước chờ nó xong.

2010-11-07

Enable subtitles in Windows 7 Media Player 12

 Original from http://techrena.blogspot.com/2009/02/enable-subtitles-in-windows-7-media.html

Lâu rồi không xem phim trên PC, tự nhiên hôm nay mở lên thì không lên subtitles dù có srt, smi, lúc trước mình vẫn xem trên XP bình thường. Search trên net ra cái bài enable subtitles. Các làm là rename 1 cái file tên mfpmp.exe thành mfpmpe.exe. File này nằm trong Windows\System32 folder thường là C:\Windows\System32. Vì nó nằm trong Windows folder nên để rename file này thì cần có quyền rename, thực hiện bằng cách take ownership và thêm security options write cho accout đang sử dụng.

Để take ownership thực hiện Properties -> Tab Security -> Chọn Advanced -> Tab Owner -> Chọn edit và chuyển ownership sang account đang sử dụng.


 Quay lại Tab Security chọn edit và chỉnh full control cho account đang sử dụng.

Nếu thấy hơi rắc rối thì có thể thử như cách command line, mở command line bằng Windows logo + R, gõ cmd.
Thực hiện lệnh takeown /f C:\Windows\System32\mfpmp.exe 
Tiếp theo thực hiện tiếp lệnh icacls để modify ACL Access Control List icacls C:\Windows\System32\mfpmp.exe /grant (user name):F, với user name là account đang sử dụng ví dụ testbug thì command line là
icacls C:\Windows\System32\mfpmp.exe /grant testbug:F

OK bây giờ thì có thể rename file, nếu chưa được thì thực hiện thêm gpupdate, nếu vẫn không được thì restart.

Sau khi đã rename xong thì có thể enable subtitles, lưu ý là phải có Direct VobSub đã được installed. Nếu chưa có Direct VobSub thì bạn nên cài KLite Codec có include Direct VobSub.

2010-11-05

Mac OSX, shortcut key (phím tắt), softwares

Mình chỉ dùng Mac OSX để test và thứ và cũng chỉ dùng để code, nhưng có lẽ vẫn không thể quen với nó dễ dàng. Dù trước giờ có dùng nhưng ngoài để code cũng chỉ lướt net và chat thôi. Để dùng thường xuyên (tạo, edit tài liệu, design ...) thì đúng là phải dùng nhiều phím tắt hơn là Windows. Post một vài thứ mình đã phải mò hay search lúc trước khi mới dùng Mac, một vài software cho mình hay dùng ngoài những phần mềm của Apple.

Softwares:
http://www.mediafire.com/?y6hb7no7vin5y share mấy cái softs ở đây.
AppZapper v2.0.1 để uninstall app
Paragon NTFS for Mac v8.0.0 đọc và ghi được NTFS như USB chẳng hạn không dùng thì chỉ read được thôi
Speed Download 5.2.8 như IDM bên Wins
Coda 1.6.12 code web
Microsoft Office 2011 v14.0.0 chưa up lên để split rồi up sau :-)

Một vài cái khác download free như Skype for Mac, Yahoo! Messenger for Mac, Picasa, Firefox, Google Chrome, Adium (chat), VideoLan (VLC xem phim, nghe nhạc nhiều format hơn iTunes) 

MonoDevelop code C#
XAMPP web server như WAMP server bên Wins
Eclipse code mấy thứ khác
MySQL Workbench database design

Shortcut keys:
C lúc khởi động để boot từ CD
Eject ngay góc trên bên phải để eject CD/DVD (lúc khởi động) nếu bị kẹt đĩa.
Command + V lúc khởi động để vào Verbose mode
Command + S lúc khởi động để vào single user mode

Command + W để đóng cửa sổ
Command + H để hide cửa sổ
Command + M để minimize xuống dock
Command + Q quit application
Option + Command + W đóng tất cả cửa sổ
Command + Right Arrow để expand folder (có file và folder con) khi folder hiển thị dạng list (có dấu mũi tên chỉ qua)
Command + Left Arrow công dụng ngược lại
Option + Command + Up Arrow đóng window hiện tại và open parent folder (folder cha, trên 1 cấp)
Option + Command + D show/hide dock 

Shift + Command + Q bản option logout (để 1 phút nó tự logout)
Shift + Option + Command + Q logout luôn
Shift + Command + Delete dùng trong Finder để empty trash
Shift + Option + Command + Delete silence empty trash (không hiển thị confirm dialog)

Command + N trong Finder để new window
Command + D duplicate (make a copy)
Command + L tạo một alias (dạng shortcut)
Command + R show original (dạng find location của shortcut)
Command + Delete move to trash
Command + E để eject USB, CD/DVD hay mount item

Shift + Command + H vào home
Shift + Command + A vào application
Shift + Command + C vào computer
Shift + Command + F vào Favorites

Control + Eject hiển thị bản option Restart, Sleep, Shutdown
Control + Command + Eject đóng toàn bộ application và restart
Option + Command + Eject sleep

Về screen capture trong Mac thì được tích hợp sẵn
Shift + Command + 3 tự động capture desktop va save dạng png.
Shift + Control + Command + 3 capture và save vào clipboard 
Shift + Command + 4 copy một phần của desktop.
Shift + Command + 4 nhấn thêm space sẽ chụp window
Thêm Control để thực hiện copy vào clipboard thay vì save dạng png
Có thể dùng Utilities Grab thay vì nhấn phím tắt để capture.

Quan trọng khi đọc văn bản hay duyệt web trên Wins hay dùng Page Up/Page Down thì sẽ chuyển thành
Function + Up/Down Arrow hay Shift + Space Bar/Function Space Bar (nút to hơn dễ bấm)
Thêm nữa nếu không dùng mouse thì để ra chuột phải nhấn Control + chuột trái (trên touchpad có mỗi cái chuột trái)
Drag n drop thì mặc định là copy, để move thì nhấn thêm Command
Home/End thì thay bằng Control + A/Control + E (hic hic quan trọng)

2010-10-21

Install Mac OS X Snow Leopard on a PC using VMware

Sau khi vật vã cài lại con MBP vì DVD gốc thì mất mà DVD source mua thì bị khùng, mình cài lại SL trên VMware để code cho tiện. Nếu muốn install thì thực ra chỉ cần search 1 chút xíu sẽ rất nhiều tutorials. Ví dụ link trên online tech tips Install Mac OS X Snow Leopard on a PC using VMware. OK, lúc trước mình cũng theo hướng dẫn trong đó là ổn, nhưng tiện đây note lại 1 chút xíu những điểm cần biết nếu ai search ra hy vọng giúp được ít nhiều:
  1. Cài đặt VMware Workstation, download version v7.1.2.301548 tại đây Part 1, Part 2, Part 3, Part 4
  2. Dùng pre-configured VMware virtual machine file để install Snow Leopard, dùng Darwin (hỗ trợ cả PowerPC và x86) để boot. Sau khi boot được thì sẽ cài Mac bằng DVD (có thể DVD-DL chứa bản SL Retail hoặc từ file ISO). Download pre-configured VMware virtual machine file. Muốn sửa tên mấy file trong đó ví dụ 'Mac OS X Server 10.6' thành một cái gì khác thì edit lại file 'Mac OS X Server 10.6.vmdk' config disk, 'Mac OS X Server 10.6.vmx' config virtual machine và 'Mac OS X Server 10.6.vmxf'.
  3. Mở pre-configured VM file, điều chỉnh các option ví dụ processsors là 2, DVD sử dụng darwin_snow.iso, hoặc extend disk.
  4. Lưu ý cầu hình trong config virtual machine file (.vmx) hai giá trị displayName = "Mac OS X Server 10.6" có thể sửa tên hiển thị trong VMware Workstation và guestOS = "darwin10" (đang dùng x84). Với x64 thì sửa lại thành darwin10-64.
  5. Power On, nếu có thông báo lỗi 'Mac OS X is not supported with software virtualization. To run Mac OS X you need a host on which VMware Workstation supports hardware virtualization.' thì có nghĩa hiện tại máy không hỗ trợ virtualization (ảo hóa). Có 2 trường hợp xảy ra một là phần cứng không hỗ trợ, hai là chưa enabled tính năng này. Nếu chưa enabled tính năng này thì boot lại máy vào BIOS enabled lên. Để kiểm tra có processor có hỗ trợ hay không dùng Hardware-assisted virtualization (HAV) detection tool. Download HAV tool và xem thêm cách config BIOS. Nếu chắc chắn là processor hỗ trợ virtualization nhưng không tìm thấy option để toggle trong BIOS thì nên update BIOS (ví dụ update BIOS của Dell A12 lên A17).
  6. Bảng tham khảo VT (Virtualization Technology) có thể xem tại Wiki hoặc bảng cho 1 số CPUs search copy luôn vào đây, bảng bên dưới. Find (Ctrl + F) để xem CPU có hỗ trợ VT.
  7. Nếu install bằng DVD-DL Retail thì sau khi boot bằng darwin_snow.iso nhấn F8 để chọn boot option chuyển lại auto detect để sử dụng physical DVD. Install như hướng dẫn của installer.
  8. Nếu install bằng SL Retail ISO (convert từ DMG sang ISO) thì chỉ việc setup DVD dùng SL Retail ISO và install bình thường. Dùng Mac OSX Snow Leopard Retail v10.6.3 bằng torrent tại đây sau khi unrar sẽ được file .dmg, torrent file size 7.54GB, seeds ~40/197. Lấy UltraISO (download version v9.36.2750) open và convert .dmg sang iso (lưu ý open kiểm tra trước khi convert). Ví dụ như hình dưới không hiển thị được tên file -> có vấn đề gì đó (open bị lỗi).

  1. Sau khi install, nếu Power On mà chỉ dừng lại màn hình quả táo thì shutdown và chỉnh lại trong file config giá trị smc.present thành FALSE.
  2. OK mọi việc xong xuôi.
Happy programming ...

Desktop CPUs
-------------------------------------------------
- Core 2 Duo
E4300/4400/4500/4600/4700 NO
E6300/6320/6400/6420/6540/6550 YES
E6600/6700/6750/6850 YES
E7200/7300/7400/7500 NO
E8190 NO
E8200/8300/8400/8500/8600 YES
- Core 2 Extreme
QX6700/6800/6850 YES
QX9650/9770/9775 YES
X6800 YES
- Core 2 Quad
Q6600/6700 YES
Q8200/8200S/8300/8400/8400S NO
Q9300/9400/9400S YES
Q9450/9550/9550S/9650 YES
- Core i7/Core i7 Extreme
I7-920/940 YES
I7-965 YES
-Pentium D/Pentium EE
805/820/830/840 NO
915/925/935/945 NO
920/930/940/950/960 YES
955/965 YES
- Pentium for Desktop
E2140/2160/2180/2200/2220 NO
E5200/5300/5400 NO

Mobile CPU products

-------------------------------------------------
- Core 2 Duo Mobile
L7200/7300/7400/7500 YES
P7350/7450 NO
P7370 YES
P8400/8600/8700/9500/9600 YES
SL9300/9400/9600 YES
SP9300/9400/9600 YES
SU9300/9400/9600 YES
T5200/5250/5270/5300/5450/5470 NO
T5500/5600 YES
T5550/5670/5750/5800/5850/5870/5900 NO
T6400/6570 NO
T7100/7200/7250/7300/7400 YES
T7500/7600/7700/7800 YES
T8100/8300 YES
T9300/9400/9500/9550/9600/9800 YES
U7500/U7600 YES
- Core 2 Extreme Mobile
QX9300 YES
X7800/7900 YES
X9000/9100 YES
- Core 2 Quad Mobile
Q9000 YES
Q9100 NO
- Core 2 Solo
SU3300/3500 YES
U2100/2200 YES
- Core Duo
L2300/2400/2500 YES
T2050/2250 NO
T2300/2400/2500/2600/2700 YES
T2300E/2350/2450 NO
U2400/2500 YES
- Core Solo
T1300/1400 YES
T1350 NO
U1300/1400/1500 YES

2010-10-18

Install OS X Snow Leopard from a USB flash drive

Original post from http://www.maciverse.com/install-os-x-snow-leopard-from-usb-flash-drive.html

Install OS X Snow Leopard from a USB flash drive

by Dan 
If you enjoy this article and other information provided here at Maciverse.com, be sure to keep up with the latest Mac hints, tips, and more by following us on twitter @Maciverse or by subscribing to our feed.

The steps below will guide you through how to Install OS X Snow Leopard from a USB Flash Drive. If you want to skip the steps and get your USB installation drive quickly, check out our pre-configured USB Snow Leopard Installation Drive. Read on if you’d like to create a USB Installation yourself.
Apple officially released Snow Leopard yesterday and consumers could find the latest version of OS X at Apple Stores and resellers across the country.
At version 10.6, Snow Leopard, focused more on improving speed and performance than adding new features to OS X. With the operating system available to customers, individuals are ready for their upgrades.

Installing OS X From a USB Drive

Like other versions of OS X, Snow Leopard can be installed from a USB drive. This is especially beneficial to Macbook Air users looking to install the OS without a DVD drive. To do this, you’ll need to prepare your USB drive with the installation files. Like many of our other Mac Help articles, the steps listed below worked particularly for Snow Leopard but should also work for installing OS X from USB on Leopard.
The installation files sit at 6.2gb on the Snow Leopard DVD, so you’ll probably need a drive that has at least 8gb available. If you want your installation files to last against the elements, check out this 8 GB Water/Shock Resistant USB flash drive. Or something a bit more interesting, the USB Humping Dog… Although I don’t believe that has enough disk space.
After you’ve gotten the correct USB device, connect it to your Mac and prepare it with the Snow Leopard installation files by following these steps:
NOTE:Depending on your flash drive, you may need to follow steps 5 – 7 on on installing onto a USB drive to make sure the drive is bootable before you get start.
  1. Open Disk Utility and select the Flash Drive
  2. Select the Erase tab on the right and then set Format to Mac OS Extended (Journaled). Name the partition you’ll be creating Snow Leopard or OS X Install so you can keep track of your installation device. After you’ve done this, click the Erase button.
  3. After Disk Utility finishes erasing your old data on the flash drive and setting it as a new partition, it will be ready for the Snow Leopard install files. Select the Restore tab at the top and then drag the Snow Leopard DVD to the Source field. Select your USB device for the Destination file. Click Restore and wait for the restoration to finish (about 20 minutes).
  4. If the restoration worked correctly you should be able to open your USB device and see the Leopard installation files. If you try and click the Install OS X Snow Leopard icon, you’ll get the message below telling you you can’ install OS X from this volume. IGNORE the message. The next steps will walk you through the installation steps.
  5. Now that the installation files are successfully on your USB device, be sure to remove the Snow Leopard installation DVD from your drive. Next, restart your Mac and when it first starts to reboot, be sure to hold down the option (alt) key on your keyboard. After a few seconds at least two volumes should appear for you to select from for installation. One of those will be the USB drive we just prepared. Select it.
  6. After the Snow Leopard installation software boots from your USB drive, follow the on screen instructions for installation. It took about 38 minutes to install Snow Leopard on my machine from the USB drive. I’m curious to see how this compares to the average Mac users, please leave a post in the comments letting us know how long it took on your machine.
  7. After the installation finishes, it will reboot your computer into your new upgraded version of OS X, version 10.6 Snow Leopard
This method works for installing OS X Snow Leopard onto a Mac from a USB Drive. It should also work for installing Leopard or other older versions of OS X on Intel Based Macs. Check back often for additional help and tips for your Mac

2010-08-19

The future of XForms

Mấy hôm nay mình ngồi research một số nền tảng để build UI cho các dự án sắp tới. Mục tiêu là cross-flatform, chạy trên cả web và desktop environment. Tất nhiên là hướng tới 'rich client', build UI dynamically và có khả năng validate data dựa trên XSD chẳng hạn.

Nói thì vậy thôi chứ thiệt ra chẳng có gì mới. Toàn bộ các ông lớn như Sun, Microsoft, Oracle, IBM, Mozilla ... hiện tại cũng đang có những project nhằm đạt được những điều đó. Và vì nhiều thứ quá nên mình có một chút confused vì căn bản chẳng thể có thời gian thử hết tất cả để biết là cái gì hợp với mình. Đúng là thời đại hỗn loạn XAML/WPF rồi MXML, XUL, XForms...

Rồi có lẽ mình focus vào XUL và XForms. Nhưng chọn XUL thì là có mối lo khác, nếu nó có lỗi thì sao, rà sơ qua stackoverflow thấy ít người recommend XUL? Đến cả Firefox kêu drop XUL (remote XUL) khỏi Firefox 4 khiến bao nhiêu developer vào comment tranh cãi. Dù rằng chỉ là remote XUL nhưng rõ ràng là XUL có một cái gì đó ko chắc chắn (I think ...) mà đáng ra phát triển bao nhiêu năm thì phải có một sự vững chãi?


Bây giờ thì focus vào XForms, đang research XForms engine. Với web thì có lẽ OK rồi còn desktop thì mới tìm hiểu Apogee Project. Giống 1 câu trong guidance của Prism "... although there is no single way to evaluate a solution ..." thật không hề đơn giản. Đơn giản là một khi đã focus thì cố lên.

2010-07-10

WPF and Silverlight Framework - Dùng Prism để xây dựng ứng dụng WPF/Silverlight


Sử dụng Prism để xây dựng ứng dụng WPF/Silverlight

Khi mấy cái projects sẽ làm đụng đến WPF thì mình lại phải đi tìm hiểu trước 1 đám framework mới hy vọng chọn 1 cái khả dĩ dùng được rồi document lại, note lại những thứ cần chú ý rồi viết hướng dẫn ... Tất nhiên là try khác với use vì vậy để sử dụng được hay không cũng try cái đã. Nếu personal thì chắc cũng chẳng cần framework, mình chỉ viết vài cái toy thì túc tắc cái gì không giải quyết được lại Googling. Có thể list ra nhiều framework nhưng có vẻ nổi nhất là Caliburn và Prism hay ít nổi hơn là WAF. Đã định try thật kỹ cái Prism từ 2 năm trước :D nhưng rồi cũng xem sơ sơ. Giờ đã xem được 1 đoạn dài nên ngồi viết lại chút xíu thay đổi không khí. Đến khi xong thằng này thì sẽ coi tiếp Caliburn xem. Nhớ lại cái đám CAB/SCSF giờ cũng quăn 1 đống, hic xung quanh phát triển nhanh quá theo ko kịp.

Giới thiệu
Nối tiếp CAB/SCSF Patterns & Practices phát triển một guidance mới với mục tiêu hỗ trợ việc xây dựng ứng dụng với WPF, phiên bản đầu tiên gọi là Prism 1.0 hay Composite Application Guidance for WPF version 1.0 vào tháng 6 năm 2008. Sau đó Prism được bổ sung Silverlight gọi là Prism 2.1 hay Composite Application Guidance for WPF and Silverlight version 2.1 dành cho Silverlight 3 được ra mắt vào tháng 10 2009. Version tiếp theo là Prism 2.2 dành cho Silverlight 4 vào tháng 5 năm 2010 là một minor update của Prism 2.1 (các project chuyển qua Visual Studio 2010, target vào Silverlight 4 và update Silverlight Toolkit).

Hiện tại Prism có version 4.0 drop 3 dành cho Silverlight 4 vào ngày 1 tháng 7 năm 2010 (bài viết này là ngày 10/7/2010) với Microsoft Visual Studio 2010, Microsoft .NET Framework 4.0, Microsoft Silverlight 4, Microsoft Silverlight 4 Tools for Visual Studio 2010.

Composite Application Guidance là gì?
Là một bộ các guidance tức các chỉ dẫn bao gồm các tham khảo, ví dụ cài đặt (reference implementation), reusable library code được gọi là Composite Application Library, tài liệu, QuickStarts và hand-on labs. Đối tượng hướng tới là các software architects và developers thực hiện xây dựng các enterprise-level applications sử dụng WPF hay Silverlight.

Những loại ứng dụng này thông thường bao gồm nhiều màn hình screens, nhiều tính năng, khả năng tương tác với user linh hoạt, hiển thị dữ liệu trực quan ... Một phần quan trọng là các ứng dụng này có đặc điểm "built to last" và "built for change". Có nghĩa là các ứng dụng được mong đợi là có vòng đời tính bằng nhiều năm và có khả năng thay đổi theo những yêu cầu mới mà các yêu cầu này chưa biết trước (new and unforeseen requirements). Vì vậy ứng dụng ban đầu có thể nhỏ và được tạo thành từ những thành phần liên độc lập, kết yếu với nhau (composed of multiple independent and loosely-coupled pieces).

Các phần có trong Guidance
Guidance bao gồm các thành phần sau:
  • Composite Application Library và Unity binaries hay source code
  • StockTrader Reference Implementation là một ứng dụng mẫu dựa trên yêu cầu thực tế (real-world scenario). Đây là một tham khảo tốt để tìm hiểu những vấn đề được xác định và giải quyết như thế nào khi xây dựng composite applications.
  • 4 QuickStarts: UIComposition QS, EventAggregation QS, Modularity QS và Commanding QS là những ứng dụng nhỏ focus vào một mục tiêu cụ thể như UI composition, modularity, commanding, event aggregation ...
  • Composite Application Guidance Hands-On Lab
  • API Documentation
  • Composite Application Guidance Documentation


Stock Trader RI

Documentation
Có thể dùng diagram dưới đây để xem các thành phần trong Composite Application Guidance Documentation.
Composite Application Guidance

Trong trường hợp đã làm quen với CAB, Prism có một tài liệu riêng cho CAB developer Composite Application Guidance for CAB Developers

Home site
Home site của Prism tại địa chỉ http://compositewpf.codeplex.com/.

System requirements
Các yêu cầu phụ thuộc vào 2 vấn đề chính cần chú ý là phiên bản của Visual Studio và Silverlight.
Nếu dùng Visual Studio 2010 hay Silverlight 4 thì version của Prism tương ứng là Prism 2.2 (for Silverlight 4) - May 2010 hay Prism 4.0 Drop 3.
Nếu dùng Visual Studio 2008 thì chúng ta dùng Prism 2.1. Các yêu cầu cụ thể như sau:
·         Microsoft Visual Studio 2008 SP1
·         Microsoft .NET Framework 3.5 SP1 (.NET Framework 3.5 bao gồm WPF)
·         Microsoft Silverlight (nếu tạo ứng dụng Silverlight)
·         Microsoft Silverlight 3 Tools for Visual Studio 2008 SP1 (nếu tạo ứng dụng Silverlight)

Tham khảo
Article Patterns For Building Composite Applications With WPF - MSDN Magazine September/2008 
Prism resources at Channel9 MSDN



2010-06-17

VisualTreeHelper.HitTest và UserControl

Từ khi chuyển qua WPF nhiều thứ thay đổi, kể cả các thói quen khi code WinForms. Ví dụ trong trường hợp nào đó, mình nghĩ chức năng tương tự của WinForms nhưng WPF lại không có. Ví dụ khi click nghĩ đến bounds của control, rồi nghĩ tới 1 cái gì đó đại loại hit test thế rồi nó sẽ dẫn đến VisualTreeHelper.HitTest của WPF chẳng hạn. Nhưng mọi chuyện đâu có tuần tự tốt đẹp như vậy, sẽ có nhiều thứ để nghĩ hơn.

Ví dụ có UserControl như sau:
-->
<UserControl x:Class="TestHitTest.DemoControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="200">
    <Grid>
        <Label Content="This is a demo control" />
        <Rectangle Fill="#FF1E59C1" Stroke="Black" HorizontalAlignment="Left" Margin="18,18,0,0" VerticalAlignment="Top" Width="93" Height="48" Opacity="0.7"/>
        <Rectangle Fill="#FF83A3DA" Stroke="Black" Margin="71,29,80,0" VerticalAlignment="Top" Height="56" Opacity="0.7"/>
        <Rectangle Fill="#FF2D3441" Stroke="Black" HorizontalAlignment="Left" Margin="53,47,0,0" VerticalAlignment="Top" Width="48" Height="38" Opacity="0.7"/>
        <Rectangle Fill="#FF97A2B5" Stroke="Black" HorizontalAlignment="Left" Margin="18,75,0,0" VerticalAlignment="Top" Width="53" Height="53" Opacity="0.7"/>
        <Rectangle Fill="#FF7AA4EE" Stroke="Black" HorizontalAlignment="Left" Margin="32,96,0,114" Width="55" Opacity="0.7"/>
        <Rectangle Fill="#FF3E547A" Stroke="Black" HorizontalAlignment="Right" Margin="0,56,31,0" VerticalAlignment="Top" Width="102" Height="56" Opacity="0.7"/>
    Grid>
UserControl>

  Trong main win chứa 2 user control: 1 bên trái và một bên phải
-->
<Window x:Class="TestHitTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestHitTest" Title="Window1" Width="600" Height="300">
    <Grid x:Name="_grid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50*" />
            <ColumnDefinition Width="50*" />
        Grid.ColumnDefinitions>
        <local:DemoControl x:Name="_leftControl" Grid.Column="0" />
        <local:DemoControl x:Name="_rightControl" Grid.Column="1" />
    Grid>
Window>


Dạng như sau:












Bây giờ đơn giản khi click chúng ta cần xác định click vào user control bên phải hay bên trái và chúng ta đang đề cập VisualTreeHelper.HitTest.

Test thử HitTest
-->
namespace TestHitTest
{
    ///
    /// Interaction logic for Window1.xaml
    ///
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            MouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
        }

        void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var pt = e.GetPosition(_grid);
            var area = new EllipseGeometry(pt, 1, 1);
            Debug.WriteLine("--- Demo hit test ---");
            VisualTreeHelper.HitTest(
                _grid,
                filter =>
                {                   
                    Debug.WriteLine("Pass through filter " + filter);
                    return HitTestFilterBehavior.Continue;
                },
                result =>
                {
                    Debug.WriteLine("Pass through result " + result.VisualHit);
                    return HitTestResultBehavior.Continue;
                },
                new GeometryHitTestParameters(area)
            );
        }
    }
}

OK run và click ta được 1 cái kết quả như sau
-->
--- Demo hit test ---
Pass through filter System.Windows.Controls.Grid
Pass through filter TestHitTest.DemoControl
Pass through filter System.Windows.Controls.Border
Pass through filter System.Windows.Controls.ContentPresenter
Pass through filter System.Windows.Controls.Grid
Pass through filter System.Windows.Shapes.Rectangle
Pass through result System.Windows.Shapes.Rectangle
Pass through filter System.Windows.Shapes.Rectangle
Pass through result System.Windows.Shapes.Rectangle
Pass through filter System.Windows.Shapes.Rectangle
Pass through result System.Windows.Shapes.Rectangle
Pass through filter System.Windows.Controls.Label: This is a demo control
Pass through filter System.Windows.Controls.Border
Pass through result System.Windows.Controls.Border

Bây giờ chỉnh 1 chút phần filter. Như đã biết filter sẽ lọc những thứ không cần thực hiện hit test trước khi cho ra kết quả. Theo code bên dưới khi đến DemoControl thì không cần duyệt children nữa.
-->
void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var pt = e.GetPosition(_grid);
    var area = new EllipseGeometry(pt, 1, 1);
    Debug.WriteLine("--- Demo hit test ---");
    VisualTreeHelper.HitTest(
        _grid,
        filter =>
        {
            Debug.WriteLine("Pass through filter " + filter);

            if (filter.GetType().IsAssignableFrom(typeof(DemoControl)))
            {
                return HitTestFilterBehavior.ContinueSkipChildren;
            }
            else
            {
                return HitTestFilterBehavior.Continue;
            }
        },
        result =>
        {
            Debug.WriteLine("Pass through result " + result.VisualHit);
            return HitTestResultBehavior.Continue;
        },
        new GeometryHitTestParameters(area)
    );
}


Kết quả nghèo nàn như sau:

-->
--- Demo hit test ---
Pass through filter System.Windows.Controls.Grid
Pass through filter TestHitTest.DemoControl

Có nghĩa là sao,  phải chăng VisualTreeHelper.HitTest không nói rõ ràng cho lắm. Trong phần result không thèm đếm xỉa tới UserControl mà coi UserControl là một collection của các base elements. Như vậy filter chỉ dùng để hạn chế còn trong phần hit test result thì không có khái niệm user control. Trong trường hợp như vậy thì xử lý ntn?

Chúng ta sẽ thực hiện tìm parent cho hit test result
-->
public static T FindVisualParent<T>(DependencyObject child)
    where T : DependencyObject
{

    // get parent item
    DependencyObject parentObject = VisualTreeHelper.GetParent(child);

    // we’ve reached the end of the tree
    if (parentObject == null) return null;

    // check if the parent matches the type we’re looking for
    T parent = parentObject as T;

    if (parent != null)
    {
        return parent;
    }
    else
    {

        // use recursion to proceed with next level
        return FindVisualParent<T>(parentObject);
    }
}

OK lúc này hit test result sửa lại như sau (có vẻ tạm ổn):

 
-->
void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var pt = e.GetPosition(_grid);
    var area = new EllipseGeometry(pt, 1, 1);
    bool isLeft = false;
    bool isRight = false;

    Debug.WriteLine("--- Demo hit test ---");
    VisualTreeHelper.HitTest(
        _grid,
        null,
        result =>
        {
            Debug.WriteLine("Pass through result " + result.VisualHit);
            IntersectionDetail detail = ((GeometryHitTestResult)result).IntersectionDetail;

            switch (detail)
            {

                case IntersectionDetail.FullyContains:
                case IntersectionDetail.Intersects:
                case IntersectionDetail.FullyInside:
                    Debug.WriteLine(result.VisualHit.ToString());
                    DemoControl control = FindVisualParent<DemoControl>(result.VisualHit);

                    if (control != null)
                    {

                        if (control.Equals(_leftControl))
                        {
                            isLeft = true;
                            Debug.WriteLine("Click on left control");
                        }
                        else if (control.Equals(_rightControl))
                        {
                            isRight = true;
                            Debug.WriteLine("Click on right control");
                        }
                        return HitTestResultBehavior.Stop;
                    }
                    return HitTestResultBehavior.Continue;
                default:
                    return HitTestResultBehavior.Stop;
            }
        },
        new GeometryHitTestParameters(area)
    );
}