タブ(TabPage)毎に異なるコンテキストメニューを開く
ここには、タブをマウスの右ボタンで押し、そのボタンを離したときにタブに応じたコンテキストメニューを開くC#のソースコードを載せてある。このコンテキストメニューの開き方はVisual Studioでのそれに近い。
TabPageに直接コンテキストメニューを設定すると、上のタブ部分での右クリックに反応してくれない。
だからTabControlにコンテキストメニューを設定しないといけない。しかし、タブ毎に異なるコンテキストメニューを設定するメンバは無いし、クリックされたタブを簡単に取得できるメンバも無い。
ウィンドウメッセージなら、クリックされたタブが分かるらしいけど、ドトネで作ってるんだから、ドトネの中でやりたい。
そしたら以下のようなプログラムになった。短いし、要所要所でコメント入れてるのですぐ読めると思う。おおざっぱな流れは
- tabControl.MouseDownでクリックしたタブを取得
- tabControl.MouseUpでマウス右ボタンだったなら明示的にコンテキストメニューを開くよう指示
- contextMenuStrip.Openingで、タブがクリックされていたなら、タブにあった項目を用意してコンテキストメニューを開く
以下ソースコード
using System; using System.Windows.Forms; using System.ComponentModel; public class Form1 : Form { TabControl tabControl = new TabControl(); TabPage tabPage1 = new TabPage(); TabPage tabPage2 = new TabPage(); ContextMenuStrip contextMenuStrip = new ContextMenuStrip(); ToolStripMenuItem toolStripMenuItem1 = new ToolStripMenuItem(); ToolStripMenuItem toolStripMenuItem2 = new ToolStripMenuItem(); // クリックしたタブページ。タブがクリックされた瞬間だけタブページへの参照を入れる。それ以外の時はnull TabPage clickedTabPage = null; public Form1() { // コンテキストメニューの項目 toolStripMenuItem1.Text = "toolStripMenuItem1"; toolStripMenuItem2.Text = "toolStripMenuItem2"; toolStripMenuItem1.Click += delegate (object sender, EventArgs e) { MessageBox.Show(sender.ToString()); }; toolStripMenuItem2.Click += delegate (object sender, EventArgs e) { MessageBox.Show(sender.ToString()); }; // マウスクリックしたタブをthis.clickedTabPageに取得 tabControl.MouseDown += delegate (object sender, MouseEventArgs e) { this.clickedTabPage = null; for (int i = 0; i < tabControl.TabCount; i++) { if (tabControl.GetTabRect(i).Contains(e.X, e.Y)) { this.clickedTabPage = (TabPage)tabControl.GetControl(i); tabControl.SelectedTab = this.clickedTabPage; } } }; // マウスの右ボタンが離された時にコンテキストメニューを開くよう指示 tabControl.MouseUp += delegate (object sender, MouseEventArgs e) { if (this.clickedTabPage != null) { if (e.Button == MouseButtons.Right) { contextMenuStrip.Show((TabControl)sender, e.Location); } } }; // コンテキストメニューを開く直前にコンテキストメニューの項目を組み立てる contextMenuStrip.Opening += delegate (object sender, CancelEventArgs e) { ContextMenuStrip menu = (ContextMenuStrip)sender; if (this.clickedTabPage != null) { // タブがクリックされていたならコンテキストメニューを開く toolStripMenuItem1.Text = this.clickedTabPage.Text + " : " + "toolStripMenuItem1"; toolStripMenuItem2.Text = this.clickedTabPage.Text + " : " + "toolStripMenuItem2"; menu.Items.Clear(); menu.Items.Add(toolStripMenuItem1); menu.Items.Add(toolStripMenuItem2); this.clickedTabPage = null; } else { // タブがクリックされてないならコンテキストメニューを開かない e.Cancel = true; } }; // 最初に項目が追加しておかないと、初回だけコンテキストメニューが出ない。何で? contextMenuStrip.Items.Add(new ToolStripMenuItem()); // タブの表示文字列 tabPage1.Text = "tabPage1"; tabPage2.Text = "tabPage2"; // tabControlにタブとコンテキストメニューを設定 tabControl.TabPages.Add(tabPage1); tabControl.TabPages.Add(tabPage2); tabControl.ContextMenuStrip = contextMenuStrip; this.Controls.Add(tabControl); } public static void Main() { Application.Run(new Form1()); } }
フィールドclickedTabPageは、TabControlのサブクラスに含めた方が適切かな
urxvtで任意のキーでセレクションのペースト
urxvt-unicode (urxvt) でのセレクション(PRIMARY)のペーストはShift-Insertに割り当てられている。このキーバインドはホームポジションから遠く押しにくいので、他のキーバインドでペーストできるようにする。
問題点
バージョン9.07のurxvtは、PRIMARYのペーストしかできないうえ、ペーストのキーバインドがShift-Insertから変えられないっぽい(ハードコーディングされてる)
方法
urxvtはperlで機能拡張できる。perlを使ってxsel*1コマンドを呼び出し、セレクションの内容を端末に書き出す。
ここでの設定
- Alt-v
- PRIMARYのペースト
- Ctrl-Alt-v
- CLIPBOARDのペースト
ここではAlt-vと表記しているが、設定ファイル中ではM-vとする。
以下設定ファイル
~/.Xresources
URxvt.perl-lib: /home/willowlet/.urxvt/ URxvt.perl-ext-common: default,x-selection URxvt.keysym.M-v: perl:x-selection:paste_primary URxvt.keysym.C-M-v: perl:x-selection:paste_clipboard
~/.urxvt/x-selection
#! perl sub paste_primary { my ($self) = @_; my $o = $self->locale_encode($self->selection); # 自urxvtに選択箇所があるとxselがフリーズするっぽいので場合分け if ($o) { $self->tt_write($o); } else { open my $fh, '-|', qw/xsel/ or die $!; while (<$fh>) { $self->tt_write($_); } close $fh or warn "status: $?"; } () } sub paste_clipboard { my ($self) = @_; open my $fh, '-|', qw/xsel -b/ or die $!; while (<$fh>) { $self->tt_write($_); } close $fh or warn "status: $?"; () } sub on_user_command { my ($self, $cmd) = @_; if ($cmd eq "x-selection:paste_primary") { #$self->tt_write('[p]'); $self->paste_primary; } if ($cmd eq "x-selection:paste_clipboard") { #$self->tt_write('[c]'); $self->paste_clipboard; } () }
独り言
perlで拡張できるurxvtはフリーダム。どういう事ができるかは man urxvtperl とか http://linux.die.net/man/3/urxvtperl に書いてある。
URxvt.keysym.*: command: の使い方がよく分からない。
*1:xsel-conrad
VMware Server 2.xのサポート期限は2011/06/30
VMware Server 2.xのサポート期限が近い。1.xに至っては既に終了している。
- Version 2.x
- 2011/06/30
- Version 1.x
- 2010/03/23
http://www.vmware.com/support/policies/lifecycle/general/index.html#policy_server
以下によれば、VMware Serverは終わるから、ESXiかPlayerに移行してね、とのこと。
End of General Support for VMware Server 2.0 is 2011-06-30, users
http://www.vmware.com/security/advisories/VMSA-2010-0007.html
should plan to upgrade to the newest release of either ESXi or
VMware Player.
これからVMware Serverを使う方は一考した方が良いだろう。ただしESXiに移行する場合はIntelのNICが無いとダメとかの制約があるらしい事に気をつけないといけない。
うちのサーバでもVMware Server 2.x使ってるから、ESXiに移る計画たてようかなぁ。
窓使いの憂鬱使いの憂鬱
Windows以外のOSを使おうとする時の最大の障壁は窓使いの憂鬱が無いこと。
FreeBSD上のXで使える窓使いの憂鬱的なソフトはあるのか。
私家版 窓使いの憂鬱 Linux & Mac (Darwin) 対応版
http://members.at.infoseek.co.jp/hattoushin_uma/
configureできない。変なエラー吐いて止まる。
checking whether the Boost::Regex library is available... yes configure: error: Could not link against !
調べるの面倒だし、他にも障害が出てきそうだからこれは止めよう。
xmodmap
http://x68000.q-e-d.net/~68user/unix/pickup?xmodmap
http://www.manpagez.com/man/1/xmodmap/
http://d.hatena.ne.jp/atasatamatara/20090612/1244786385
keycodeにおける5〜8個目のkeysymの意味が載ってるページ発見。
Some hints about xmodmap(1) and the X11 keyboard model
http://www.in-ulm.de/~mascheck/X11/xmodmap.html#format
5〜8番目のkeysymは、1〜4番目のと切り替えて使う。
切り替え方は、ISO_Next_Groupと言うkeysymを割り当てたキーを2回押すこと。
例)HHKB Professional JPの変換キーをISO_Next_Groupにする
keycode 129 = ISO_Next_Group keysym a = a A b B c C d D
で、変換キーを2回押すと文字グループが変更される。
するとaキーでcが入力される。
C d Dの入力はA b Bと同様で、ShiftとMode_switchの組み合わせで入力できる。
さらに変換キーを2回押すと元のa A b Bの文字グループに戻る。
この機能はXKB extensionを使ってるらしい。
XKB extension
http://homepage.mac.com/hre.i/ebug-20080920-xkb.html
http://en.wikipedia.org/wiki/Xkb
かなり柔軟性があるっぽい。大変そうだから今度調べよう。
DXライブラリで任意のフォントを使用する
はじめに
ここではDXライブラリでフォントファイル(.ttfなど)をWindowsにインストールせずそのまま利用する方法を紹介する。この方法では既存のDXライブラリにある文字列描画関数をそのまま利用する事ができる。
目次
背景
バージョン3.00eのDXライブラリでは、文字列描画に使用するフォントを変更する手段として2種類の関数が用意されている。1つはChangeFont関数、もう1つはCreateFontToHandle関数だ。しかし、通常これらの関数で指定できるフォントはWindowsにインストールされたフォントのみである。そのため、DXライブラリユーザ*1側で用意したフォントを使用するためには一工夫必要だ。
準備
以下の環境で正しく動作するのを確認した。- 動作環境
- Windows XP SP3
- 開発環境
- Visual Studio 2008 Professional (VC++2008)
- DXライブラリ(バージョン3.00e)
この環境、このバージョンで話を進める。
動作環境においてWindows2000以降の機能を使うので、Windows 95, 98, NTでは動作しないと思われる。これらに対応する方法については後述する。
方法
まずWin32APIのAddFontResourceExでフォントファイルを読み込んでおく。次にChangeFont関数などで読み込ませたフォントのフォント名を指定して、適当な文字列描画関数で文字列を出力する。最後に、プログラム終了前にRemoveFontResourceExでフォントをアンロード*2する。日向梓さんのあずきフォントを使用するサンプルを以下に示す。あずきフォントのファイル(azuki.ttf)をプロジェクトのフォルダ*3に置いておくこと。
ChangeFontに指定するフォント名を調べるには、フォントファイルを開いて「書体名」を見ればよい。
サンプルコード
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode(TRUE); // ウィンドウモードで表示 if (DxLib_Init() == -1) // DXライブラリ初期化処理 return -1; // エラーが起きたら直ちに終了 // ********** フォントのロード ********** LPCSTR font_path = "azuki.ttf"; // 読み込むフォントファイルのパス if (AddFontResourceEx(font_path, FR_PRIVATE, NULL) > 0) { } else { // フォント読込エラー処理 MessageBox(NULL,"フォント読込失敗","",MB_OK); } // ********** ここから読み込んだフォントを利用できる ********** SetFontSize(36); // 見やすさのため、フォントサイズを大きく DrawString(10, 200, "この文字はMS ゴシックです。", GetColor(255, 255, 255)); ChangeFont( "あずきフォント", DX_CHARSET_DEFAULT ) ; DrawString( 10 , 240, "この文字はあずきフォントです。", GetColor( 255 , 255 , 255 ) ); WaitKey() ; // キーの入力待ち(『WaitKey』を使用) // ********** フォントのアンロード ********** if (RemoveFontResourceEx(font_path, FR_PRIVATE, NULL)) { } else { MessageBox(NULL, "remove failure", "", MB_OK); } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 }
1行目がMS ゴシック、2行目があずきフォントになっている。
フォントファイルの置き場所
読み込むフォントファイルのパスには普通の相対パスや絶対パスも指定できる。もちろんフォルダの区切り記号「\」は2個並べないといけない。
font_path = "azuki.ttf"; // 一種の相対パス font_path = "fonts\\azuki.ttf"; // 相対パス font_path = "C:\\Documents and Settings\\user\\My Documents\\Visual Studio 2008\\Projects\\AddFontResource on DxLib\\fonts\\azuki.ttf"; // 絶対パス
絶対パスは使わない方がいいだろう。プログラムにフォントを同梱するならば相対パスを使用するべきだ。なぜなら、プログラムのユーザは、そのフォルダをどこに置くかわからないからだ。
欧文フォントを使うには
ChangeFont関数の第2引数のデフォルトはDX_CHARSET_SHFTJISとなっており、フォントの文字セットをシフトJIS文字セットにする。このため、欧文フォントは正しく適用できない。欧文フォントでも使えるようにするには、DX_CHARSET_DEFAULTを渡してデフォルト文字セットを使う様にすればよいようだ。また、日本語フォントを使用する場合であってもDX_CHARSET_DEFAULTを渡して問題無いようだ。
Windows 95, 98, NTに対応させる
上で使用したAddFontResourceExはWindows 2000以降でしか使えない。Windows 95などでは代わりにAddFontResourceを使用すればよい。ただしAddFontResourceで読み込んだフォントは、このプログラム以外のプログラムからも使用できてしまう。そのため、フォントのライセンスにより注意しなければいけないだろう。
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode(TRUE); // ウィンドウモードで表示 if (DxLib_Init() == -1) // DXライブラリ初期化処理 return -1; // エラーが起きたら直ちに終了 // ********** フォントのロード ********** LPCSTR font_path = "azuki.ttf"; // 読み込むフォントファイルのパス if (AddFontResource(font_path) > 0) { PostMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); } else { // フォント読込エラー処理 MessageBox(NULL,"フォント読込失敗","",MB_OK); } // ********** ここから読み込んだフォントを利用できる ********** SetFontSize(36); // 見やすさのため、フォントサイズを大きく DrawString(10, 200, "この文字はMS ゴシックです。", GetColor(255, 255, 255)); ChangeFont( "あずきフォント", DX_CHARSET_DEFAULT ) ; DrawString( 10 , 240, "この文字はあずきフォントです。", GetColor( 255 , 255 , 255 ) ); WaitKey() ; // キーの入力待ち(『WaitKey』を使用) // ********** フォントのアンロード ********** if (RemoveFontResource(font_path)) { PostMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); } else { MessageBox(NULL, "remove failure", "", MB_OK); } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 }
さらにPostMessageを使ってる事に注意したい。ここではウィンドウメッセージをブロードキャストする。このメッセージを適切なウィンドウプロシジャで処理しなければフォントを有効にできない。メッセージ処理のもっとも簡単な方法は、このサンプルのようにDXライブラリにまかせる事だろう。つまりDxLib_Init()とDxLib_End()の間でPostMessageすればよい。
仕組み
DXライブラリはフォントデータの生成のとき、内部でWin32APIのCreateFontを呼んでいる。そこで、CreateFontで任意のフォントファイルからのフォントを使用できるようにしてやればよい。そのためにはAddFontResourceExでフォントファイルを読み込ませる。これでDXライブラリで任意のフォントを使用できるようになるのである。まとめ
DXライブラリにおいて、任意のフォントを使用するためにはAddFontResourceExでフォントファイルを読み込ませる。これで、DXライブラリの関数ChangeFontやCreateFontToHandleで読み込ませたフォントを指定できるようになる。DXライブラリ側でこの機能を用意してくれないかな。
参考
- DXライブラリ置き場 リファレンスページ http://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_graph.html
- Win32 API フォント/テキスト http://msdn.microsoft.com/ja-jp/library/cc428274.aspx
- DXライブラリのソースコード http://homepage2.nifty.com/natupaji/DxLib/dxdload.html
- ChangeFontにおける欧文フォントの指定について http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=614
PS3にFedora 12インストール
Fedora 12のインストール
PS3に入れてたFedora 10がEOLになってた。Fedora 12へfedora-releaseパッケージでアップデートしたら、なんか画面が出てこなくなってしまった。調査するのは面倒なので新規にインストールしてしまおう。
基本的にここの手順に従ってインストールした。
PS3にFedora 12を「軽量」インストールする
- petitbootの新しいバージョンが出てた。ps3-petitboot-09.11.30-cui.bld
- ネットワークの設定ではIPを固定にした。/etc/sysconfig/network-scripts/ifcfg-eth0と/etc/sysconfig/networkの編集。
- 起動するサービスを最小限に絞った。ただしsshdは起動するようにした。
- デスクトップ関連はインストールしなかった。sshで操作するつもり。
- Cell SDK 3.1をインストールした。
- RPM Fusionリポジトリはインストールしなかった。
あと、manとかman-pages-jaとかlvとかzshとかscreenとかopenssh-clientsとかvim-commonとかvim-enhancedとかsubversionもインストールした。
WOLできるように/etc/rc.localに以下を追加
ethtool -s eth0 wol g
TortoiseSVN 1.6.6でSSH接続の時ポート指定したい
以下の様なURLの中にポート番号を指定する方法では駄目
svn+ssh://example.com:12345/path/to/repo
こちらの方法でできた。
C:\Documents and Settings\[ユーザーID]\Application Data\Subversion\configファイルの[tunnels]セクションに次のように記述する.
hoge = "C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe" -ssh -l [ユーザーID] -P 10220 -pw [パスワード]このように記述しておくことで,svn+sshではなくsvn+hogeとすることができる.
http://www.santalinux.net/blog2/?p=22