ざつだ ん。 (11/12/01~)
11/12/01
・
スレート PC プログラミング
先日の TTouchKeyboard の雑談を転記。
・
ONKYO TW2A シリーズ
12/09 に発売が延期された模様。
|
TW2A-A25Z7CK (店頭販売モデル) |
TW2A-A25Z7D (直販モデル) |
TW2A-A25Z7H (法人向けモデル) |
TW2A-A25Z7PH (法人向けモデル) |
OS |
WindowsR 7 Home Premium 32ビット 正規版
Service Pack 1 (SP1) 適用済み |
WindowsR 7 Professional 32ビット 正規版
Service Pack 1 (SP1) 適用済み |
キーボード |
Bluetooth キーボード |
- |
専用ケース |
○ |
- |
デジタイザペン |
○ |
価格 |
60,000円 前後 |
59,800円 ~ |
60,000円 前後 |
70,000円 前後 |
TW2A-A25Z7PH (法人向けモデル) を買う位なら、TW2A-A25Z7CK (店頭販売モデル) を購入して Windows Anytime Upgrade 買った方がよくないか?付属品と価格差的に。
11/12/08
・
TurboPower プロジェクト
現状を調べてみました。前回調査は半年前です。
Delphi 6 よりも前の環境/製品は省略しています。
11/12/12
・
Programming the iOS Accelerometer and Camera using Delphi and FireMonkey と DirectShow
正直な話をすると、Windows のセンサーとかカメラ (WebCam) もやらずに iOS でやるのは順序が違うんじゃないかと思うのです。とりあえず Windows で出来ることをあらかた網羅してからやるべきかと...あ、いや Tim DelChiaro 氏の記事に問題がある訳じゃないですよ。
Windows で WebCam を扱うには DSPack を使うのが簡単です...とはいえ、DirectShow そのものが面倒なので DSPack のサンプルをクラスでラッピングしてさらに簡単に使えるようにしてみました。
// -----------------------------------------------------------------------------
// DSPack を使ったカメラ (静止画) クラス
// -----------------------------------------------------------------------------
unit StillCam;
interface
uses
SysUtils, Types, DSPack, DXSUtil, DirectShow9, Graphics, Jpeg;
type
{ TStillCamera }
TStillCamera = class(TObject)
private
FActive: Boolean;
FBaseDir: string;
FDeviceIndex: Integer;
FDevices: TStringDynArray;
FFilter: TFilter;
FFilterGraph: TFilterGraph;
FSampleGrabber: TSampleGrabber;
FSysDevEnum: TSysDevEnum;
FVideoWindow: TVideoWindow;
procedure SetActive(const Value: Boolean);
procedure SetVideoWindow(const Value: TVideoWindow);
procedure SetDeviceIndex(const Value: Integer);
public
constructor Create;
destructor Destroy; override; // 使用するカメラデバイスのインデックス
property Devices: TStringDynArray read FDevices; // カメラデバイスの一覧
procedure GetBitmap(var Bitmap: TBitmap); // キャプチャ画像を Bitmap へ取り込み
procedure Capture; overload; // キャプチャ画像を連番で Jpeg 画像として保存
procedure Capture(const FileName: TFileName); overload; // キャプチャ画像に名前を付けて Jpeg 画像で保存
property Active: Boolean read FActive write SetActive; // カメラの有効/無効
property BaseDir: string read FBaseDir write FBaseDir; // 画像保存先
property DeviceIndex: Integer read FDeviceIndex write SetDeviceIndex; // デバイス (カメラ) のインデックス
property FilterGraph: TFilterGraph read FFilterGraph; // Fileter Graph
property VideoWindow: TVideoWindow read FVideoWindow write SetVideoWindow; // プレビュー用のビデオウィンドウ
end;
implementation
{ TStillCamera }
constructor TStillCamera.Create;
// コンストラクタ
var
i: Integer;
begin
FBaseDir := '';
FVideoWindow := nil;
// FilterGraph
FFilterGraph := TFilterGraph.Create(nil);
with FFilterGraph do
begin
GraphEdit := True;
LinearVolume := True;
Mode := gmCapture;
end;
// Filter
FFilter := TFilter.Create(nil);
with FFilter do
FilterGraph := FFilterGraph;
// SampleGrabber
FSampleGrabber := TSampleGrabber.Create(nil);
with FSampleGrabber do
FilterGraph := FFilterGraph;
// Devices
FDeviceIndex := -1;
FSysDevEnum := TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
if FSysDevEnum.CountFilters > 0 then
begin
SetLength(FDevices, FSysDevEnum.CountFilters);
for i:=0 to FSysDevEnum.CountFilters-1 do
Devices[i] := FSysDevEnum.Filters[i].FriendlyName;
DeviceIndex := 0;
end;
end;
destructor TStillCamera.Destroy;
// デストラクタ
begin
FFilterGraph.ClearGraph;
FFilterGraph.Active := False;
FSysDevEnum.Free;
FSampleGrabber.Free;
FFilter.Free;
FFilterGraph.Free;
inherited;
end;
procedure TStillCamera.SetActive(const Value: Boolean);
// カメラの有効/無効
begin
if FActive = Value then
Exit;
if FDeviceIndex = -1 then
Exit;
FFilterGraph.ClearGraph;
FFilterGraph.Active := False;
if Value then
begin
FFilter.BaseFilter.Moniker := FSysDevEnum.GetMoniker(FDeviceIndex);
FFilterGraph.Active := True;
with FFilterGraph as ICaptureGraphBuilder2 do
RenderStream(@PIN_CATEGORY_PREVIEW, nil, FFilter as IBaseFilter, FSampleGrabber as IBaseFilter, FVideoWindow as IBaseFilter);
FFilterGraph.Play;
end;
FActive := Value;
end;
procedure TStillCamera.SetDeviceIndex(const Value: Integer);
// デバイス (カメラ) のインデックスを設定
begin
if FDeviceIndex = Value then
Exit;
FDeviceIndex := Value;
end;
procedure TStillCamera.SetVideoWindow(const Value: TVideoWindow);
// プレビュー用のビデオウィンドウを設定
begin
FVideoWindow := Value;
if Assigned(FVideoWindow) then
FVideoWindow.FilterGraph := FFilterGraph;
end;
procedure TStillCamera.GetBitmap(var Bitmap: TBitmap);
// キャプチャ画像を Bitmap へ取り込み
begin
FSampleGrabber.GetBitmap(Bitmap);
end;
procedure TStillCamera.Capture;
// キャプチャ画像を連番で Jpeg 画像として保存
begin
Capture(FormatDateTime('"img"YYYYMMDDHHNNSS".jpg"', Now));
end;
procedure TStillCamera.Capture(const FileName: TFileName);
// キャプチャ画像に名前を付けて Jpeg 画像で保存
var
Bitmap: TBitmap;
Jpeg: TJpegImage;
dFileName: TFileName;
begin
Bitmap := TBitmap.Create;
Jpeg := TJPEGImage.Create;
try
FSampleGrabber.GetBitmap(Bitmap);
Jpeg.Assign(Bitmap);
dFileName := FileName;
if FBaseDir <> '' then
dFileName := IncludeTrailingPathDelimiter(FBaseDir) + dFileName;
Jpeg.SaveToFile(dFileName);
finally
Jpeg.Free;
Bitmap.Free;
end;
end;
end.
|
使い方は、Button ([Standard] カテゴリ) と VideoWindow ([DSPack] カテゴリ) をフォームに貼って、
uses
..., StillCam;
...
type
TForm1 = class(TForm)
VideoWindow1: TVideoWindow;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
StillCamera: TStillCamera;
public
{ Public 宣言 }
end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
StillCamera := TStillCamera.Create;
StillCamera.VideoWindow := VideoWindow1;
StillCamera.Active := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
StillCamera.Capture;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
StillCamera.Free;
end;
|
ボタンを押すと実行ファイルのある場所に日付の連番で *.jpg を生成します。このクラスでもそこそこ実用的なのですが、もうちょっと凝ってみると面白いと思います。ちょっと仕事がテンパってるので、それはまたの機会にでも...。
・
明日
ん?明日は 11/12/13 か。また "鉄ちゃんの日" なのか?
11/12/17
・
TTouchKeyboard とファンクションキー
Delphi XE2 の Update3 がリリースされ、"タッチパネルの場合、フレームの上に載せた TTouchKeyboard はキーを押しても反応しない" という QC#97941 も修正されたようですし、もう一つ TTouchKeyboard のサンプルを (...まぁ、欲を言えばサポート期間が切れていないのだから、XE にもバックポートして欲しいのですけどね)。
今日は、業務アプリによくあるファンクションキーを作ってみたいと思います。基本的なカスタムタッチキーボードの作り方は 11/26 以降の雑談を読んで下さい。キーボードレイアウト XML ファイル (FUNCTIONKEYBOARD.xml) はこうなります。
<keyboard keyboardname="Function" keyboardtype="Function" width="848" height="56" minwidth="480" minheight="32" rowheight="48">
<row topmargin="4" bottommargin="4">
<key vk="112" caption="F1" publishedname="Func01" width="48" height="48" leftmargin="6" rightmargin="2" fontsize="10" stretch="true"/>
<key vk="113" caption="F2" publishedname="Func02" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="114" caption="F3" publishedname="Func03" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="115" caption="F4" publishedname="Func04" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="116" caption="F5" publishedname="Func05" width="48" height="48" leftmargin="6" fontsize="10" stretch="true"/>
<key vk="117" caption="F6" publishedname="Func06" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="118" caption="F7" publishedname="Func07" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="119" caption="F8" publishedname="Func08" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="120" caption="F9" publishedname="Func09" width="48" height="48" leftmargin="6" fontsize="10" stretch="true"/>
<key vk="121" caption="F10" publishedname="Func10" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="122" caption="F11" publishedname="Func11" width="48" height="48" leftmargin="2" fontsize="10" stretch="true"/>
<key vk="123" caption="F12" publishedname="Func12" width="48" height="48" leftmargin="2" rightmargin="4" fontsize="10" stretch="true"/>
</row>
</keyboard>
|
普通に VK_F1 ~ VK_F12 を返すキーボードです。
uses
...Keyboard, KeyboardTypes;
...
type
TTempTouchKeyboard = class(TCustomTouchKeyboard);
TForm1 = class(TForm)
...
procedure TForm1.FormCreate(Sender: TObject);
begin
TouchKeyboard1.Align := alBottom;
TouchKeyboard1.Layout := 'Function';
TouchKeyboard1.Height := 36;
TTempTouchKeyboard(TouchKeyboard1).Buttons[ 0].Caption := 'F1: 登録';
TTempTouchKeyboard(TouchKeyboard1).Buttons[11].Caption := 'F12: 終了';
end;
|
実行時にファンクションキーボードに変更します。
こんな感じですね。多少の不満は残るかもしれませんが、簡単にファンクションメニューを実現できるのは大きなメリットだと思います。
11/12/18
・
怠け者の理論
つい最近知ったのだけれど、"プログラマの三大美徳" というのがあるそうな。
リンク先の記事の "怠慢" はちょっとニュアンスが違うと思う...原文の意味のままでいいんじゃないかと。
全体の労力を減らすために手間を惜しまない気質。
この気質の持ち主は、役立つプログラムを書いてみんなの苦労を減らしたり、同じ質問に何度も答えなくてもいいように文書を書いたりする。
よって、プログラマーの第一の美徳である。
|
無駄...確かにキライだなぁ。だから、"QC / 青 QC / RAID の仕組み" は大嫌いです。QC 情報を見てバグを把握する作業は苦ではないのですが、QC 見ても載ってなくてレポートすると RAID との重複だったり、青 QC にあって既に FT 期間を終えているのに一般的には青 QC が見えないために、同じ QC が何度も登録されては重複扱いされたりするのを見ると、その度に 「どうにかならんもんか...」 と思います。
・
プチコン (Nintendo DS)
うは、こんなのあったのか。でも、比較演算子が BASIC らしくない (等価が "==" だったり) なぁ。そういや、Google Go も全体的には C / C++ みたいなのに、代入演算子が ":=" だったり、変数宣言が変数名が先で型が後だったりするっけな...1.0 はまだなんだっけ?