参考:
猫でもわかるプログラミング
第12章 システムメニューの改造
http://www.kumei.ne.jp/c_lang/sdk/sdk_12.htm
システムメニューというのは、ウィンドウのタイトルバーのアイコンをクリックしたり、
タスクバーのボタンを右クリックしたときに出てくるメニューらしい。
そのシステムメニューに、「常に最前面に表示」なんて項目があったらいいなと常々思っていたので作ってみる。
ポイント
- システムメニューのメニューハンドルを取得 (GetSystemMenu)
- システムメニューの項目が選択されたときの処理 (WM_SYSCOMMAND)
- ウィンドウを最前面に (SetWindowPos, HWND_TOPMOST)
require 'basewin' # basewin.rb require 'Win32API' WM_PAINT = 0x000F WM_SYSCOMMAND = 0x0112 DT_WORDBREAK = 0x00000010 MF_STRING = 0x00000000 MF_UNCHECKED = 0x00000000 MF_CHECKED = 0x00000008 SC_RESTORE = 0xF120 # 元のサイズに戻す WS_EX_TOPMOST = 0x00000008 HWND_TOPMOST = -1 HWND_NOTOPMOST = -2 SWP_NOSIZE = 0x0001 SWP_NOMOVE = 0x0002 IDSM_TOPMOST = 2001 class MyWindow < BaseWindow SetBkMode = Win32API.new('Gdi32', 'SetBkMode', 'II', 'I') SetTextColor = Win32API.new('Gdi32', 'SetTextColor', 'II', 'I') TRANSPARENT = 1 GetSystemMenu = Win32API.new('User32', 'GetSystemMenu', 'II', 'I') InsertMenuA = Win32API.new('User32', 'InsertMenuA', 'IIIIP', 'I') AppendMenuA = Win32API.new('User32', 'AppendMenuA', 'IIIP', 'I') SetWindowPos = Win32API.new('User32', 'SetWindowPos', 'IIIIIII', 'I') CheckMenuItem = Win32API.new('User32', 'CheckMenuItem', 'III', 'I') def initialize(*arg) super setHandler(WM_PAINT, method(:on_paint)) setHandler(WM_SYSCOMMAND, method(:on_syscommand)) end def construct self.caption = "猫でもわかるプログラミング" move(100, 100, 300, 200) # システムメニュー @sysmenu = GetSystemMenu.call(hWnd, 0); InsertMenuA.call(@sysmenu, SC_RESTORE, MF_STRING, IDSM_TOPMOST, '常に最前面に表示(&T)'); end def on_paint(msg) SetTextColor.call(hdc, RGB(0,0,0xff)) oldbkmode = SetBkMode.call(hdc, TRANSPARENT) x, y, w, h = self.clientrect drawText("参考ページ\n猫でもわかるプログラミング!\nです。", 0+30, 0+30, w-30, h-30, nil, DT_WORDBREAK) SetBkMode.call(hdc, oldbkmode) end def on_syscommand(msg) case msg.wParam when IDSM_TOPMOST if self.exstyle & WS_EX_TOPMOST == WS_EX_TOPMOST then SetWindowPos.call(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) CheckMenuItem.call(@sysmenu, IDSM_TOPMOST, MF_UNCHECKED) else SetWindowPos.call(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) CheckMenuItem.call(@sysmenu, IDSM_TOPMOST, MF_CHECKED) end msg.retval = 0 end end end form = MyApp.newwindow(nil, MyWindow) form.create.show MyApp.application.messageloop