1. 要搭配 Video Hook Driver
2. 「Check the Cideo Hook Driver」按鈕要連線時按才有意義
2011年3月9日 星期三
2011年1月30日 星期日
Ubuntu Server 10.10 安裝 ASP.Net 網站伺服器的步驟
一、安裝 mono 以及 xsp
sudo apt-get install mono-gmcs
sudo apt-get install mono-xsp2
sudo apt-get install mono-apache-server2
sudo apt-get install libapache2-mod-mono
sudo a2enmod mod_mono
二、修改 /etc/apache2/mods-enabled/mod_mono.conf
成為以下這樣:
===== 從這裡開始 =====
AddType application/x-asp-net .aspx .ashx .asmx .ascx .asax .config .axd
DirectoryIndex index.aspx
DirectoryIndex Default.aspx
DirectoryIndex default.aspx
MonoAutoApplication enabled
MonoServerPath "/usr/bin/mod-mono-server2"
Include /etc/mono-server2/mono-server2-hosts.conf
===== 到這裡結束 =====
三、重新啟動 apache2
sudo /etc/init.d/apache2 restart
若要讓 Visual Studio 跟 MonoDevelop 共用網站專案的話
要使用「ASP.Net 應用程式」開發,不可以使用「ASP.Net 網站」開發
這樣平常就可以使用 Visual Studio 開發,要部署到 Ubuntu Server 時,再用 MonoDevelop 編譯一次就好
2010年11月7日 星期日
ASP.Net GridView 的自訂資料繫結
在論壇上,常常看到有網友提出這樣的問題:如果資料值是 Y/N,要顯示 是/否 在 GridView 上,要如何做?
這個問題有幾種解法
第一種:使用 GridView.RowDataBound 事件,搭配 TemplateField
這種方法是大部分的書上會介紹的方法
RowDataBound 事件,會傳入一個型別為 GridViewRowEventArgs 的參數 e
e.Row 指的是 GridView 剛剛做完資料繫結的列
e.Row.DataItem 指的是用來做這個列的資料繫結的資料來源,型別是 object
如果以 DataTable 或是 DataSet 做資料來源,e.Row.DataItem 實際上是一個 DataRowView
所以,如果以 DataTable 或是 DataSet 做資料來源,(e.Row.DataItem as DataRowView).Row["欄位名稱"] 可以取得欄位的資料值
接下來,就是「數格子」,要知道你的 TemplateField 是第幾欄,還要知道要做自訂資料繫結的控制項是 ItemTemplate 的第幾個控制項
(e.Row.Cells[欄索引].Controls[控制項索引] as 控制項型別).Text =
(e.Row.DataItem as DataRowView).Row["欄位名稱"].ToString()
或是要知道自訂資料繫結的控制項的 ID
(e.Row.Cells[欄索引].FindControl("控制項ID") as 控制項型別).Text =
(e.Row.DataItem as DataRowView).Row["欄位名稱"].ToString()
這種方法的缺點是
- 如果在這個TemplateField 之前,加入或是刪掉了其他欄,或是修改了 TemplateField 的 ItemTemplate,事件處理都得修改
- 如果不是以 DataTable 或是 DataSet 做資料來源,e.Row.DataItem 事實上是什麼型別?
不確定因素太多,既麻煩又複雜!強烈不建議使用這個方法
第二種:使用單純自訂資料繫結,搭配 TemplateField
這種方法直接在 TemplateField 的 ItemTemplate 中放置一個 Label,並設置 Text 屬性的資料繫結為 Text='<%# Eval("欄位名稱").ToString() == "Y" ? "是" : (Eval("欄位名稱").ToString() == "N" ? "否" : "") %>' Text='<%# Eval("欄位名稱", "{0}") == "Y" ? "是" : (Eval("欄位名稱", "{0}") == "N" ? "否" : "") %>'
簡單明瞭,只是判斷是寫在 .aspx 裡面,而且當資料值是 DbNull 的時候會發生錯誤,如果還要加上判斷是否為 DbNull 的語法就更複雜了
因此,此方法建議使用於簡單判斷以及資料欄位不允許 null 的狀況
PS: Eval("欄位名稱") 與 Eval("欄位名稱", "{0}") 的不同點在於前者回傳的是 Object,後者回傳的是 String
第三種:使用自訂資料繫結方法,搭配 TemplateField
跟第二種方法類似,只是將 Label 的 Text 屬性的資料繫結改為呼叫一個自訂方法 (必須為 public 或 protected 方法)
Text='<%# YesOrNo(Eval("欄位名稱")) %>'
並撰寫後端程式碼如下:
protected string YesOrNo(object o)
{
string s = o == DbNull.Value ? "" : Convert.ToString(o);
return s == "Y" ? "是" : (s == "N" ? "否" : "");
}
這樣的好處是
- 不用數格子
- 沒有複雜的資料繫結語法
- 無論從何種資料來源做資料繫結,都可以適用
- 可檢查資料是否為 DbNull
2010年11月3日 星期三
Delphi 5 使 DBGrid 支援滑鼠滾輪的程式碼
Delphi 5 的 TDBGrid 無法支援滑鼠滾輪移動資掉指標,而且當有 PickList 的 Column 或是 Lookup Field 下拉時
滾動滑鼠滾輪會有很奇怪的行為。
要解決這個問題,可以繼承 TDBGrid 寫一個新的 DBGrid 類別,並覆寫兩個方法:
interface
type
TNewDBGrid = class(TDBGrid)
protected
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
end;
implementation
function TNewDBGrid.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean;
begin
Result := False;
if Assigned(OnMouseWheelDown) then
OnMouseWheelDown(Self, Shift, MousePos, Result);
if (not Result) and (DataLink <> nil) and (DataLink.Active)
and (DataLink.DataSet <> nil) and (DataLink.DataSet.Active) then
begin
DataLink.DataSet.MoveBy(1);
Result := True;
end;
end;
function TNewDBGrid.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
begin
Result := False;
if Assigned(OnMouseWheelDown) then
OnMouseWheelDown(Self, Shift, MousePos, Result);
if (not Result) and (DataLink <> nil) and (DataLink.Active)
and (DataLink.DataSet <> nil) and (DataLink.DataSet.Active) then
begin
DataLink.DataSet.MoveBy(-1);
Result := True;
end;
end;
2010年9月8日 星期三
多螢幕環境下,指定螢幕顯示畫面 (C#)
private void ChangeScreen(Form aForm, int screenId)
{
// 先將 Form 設定為 Normal
aForm.WindowState = FormWindowState.Normal;
// 改 Location
aForm.StartPosition = FormStartPosition.Manual;
if (screenId < Screen.AllScreens.Length)
{
aForm.Location = Screen.AllScreens[screenId].WorkingArea.Location;
}
// 最後設定成 Maximized
aForm.WindowState = FormWindowState.Maximized;
}
2010年9月2日 星期四
多螢幕環境下,指定螢幕顯示畫面 (Delphi 5)
procedure MakeFullyVisible(AForm: TForm; AMonitor: TMonitor);
var
ALeft: Integer;
ATop: Integer;
begin
if AMonitor = nil then
AMonitor := AForm.Monitor;
ALeft := AForm.Left;
ATop := AForm.Top;
if AForm.Left + AForm.Width > AMonitor.Left + AMonitor.Width then
ALeft := AMonitor.Left + AMonitor.Width - AForm.Width;
if AForm.Left < AMonitor.Left then
ALeft := AMonitor.Left;
if AForm.Top + AForm.Height > AMonitor.Top + AMonitor.Height then
ATop := AMonitor.Top + AMonitor.Height - AForm.Height;
if AForm.Top < AMonitor.Top then
ATop := AMonitor.Top;
AForm.SetBounds(ALeft, ATop, AForm.Width, AForm.Height);
end;
呼叫方法是:
MakeFullyVisible(Form1, Screen.Monitors[0]); // 將 Form1 顯示在第一個螢幕 MakeFullyVisible(Form2, Screen.Monitors[1]); // 將 Form2 顯示在第二個螢幕
2010年4月15日 星期四
Delphi 取得實體硬碟序號 (非分割區序號)
程式
//自訂型態
type
IDEREGS = record
bFeaturesReg: Byte;
bSectorCountReg: Byte;
bSectorNumberReg: Byte;
bCylLowReg: Byte;
bCylHighReg: Byte;
bDriveHeadReg: Byte;
bCommandReg: Byte;
bReserved: Byte;
end; DRIVERSTATUS = record
bDriveError: Byte;
bIDEStatus: Byte;
bReserved: array[1..2] of Byte;
dwReserved: array [1..2] of LongWord;
end;
SENDCMDOUTPARAMS = record
cBufferSize: LongWord;
DStatus: DRIVERSTATUS;
bBuffer: array[1..512] of Byte;
end;
SENDCMDINPARAMS = record
cBufferSize: LongWord;
irDriveRegs: IDEREGS;
bDriveNumber: Byte;
bReserved: array[1..3] of Byte;
dwReserved: array[1..4] of LongWord;
end;
THdInfoType = (HD_MODEL_NUMBER, HD_SERIAL_NUMBER, HD_FIRMWARE_REVISION);
// API宣告 function DeviceIoControl (hDevice: LongWord; dwIoControlCode: LongWord; lpInBuffer: Pointer; nInBufferSize: LongWord; lpOutBuffer: Pointer; nOutBufferSize: LongWord; var lpBytesReturned: LongWord; lpOverlapped: LongWord): LongWord; stdcall; external 'Kernel32';
// 取得硬碟序號
function Get_HD_Info(DrvIdx: byte; HdInfoType: THdInfoType): String;
var
ParaIn: SENDCMDINPARAMS;
ParaOut: SENDCMDOUTPARAMS;
Sno: String;
h, br: LongWord;
i, st, ed: Integer;
PlatForm: string;
procedure GetPlatForm;
var OS: OSVERSIONINFO;
begin
OS.dwOSVersionInfoSize := SizeOf(OS);
GetVersionEx(OS);
PlatForm := 'UNK';
case OS.dwPlatformId of
VER_PLATFORM_WIN32S:
PlatForm := '32S'; // Win32S
VER_PLATFORM_WIN32_WINDOWS:
begin
if OS.dwMinorVersion = 0 then
PlatForm := 'W95' // Win 95
else
PlatForm := 'W98' // Win 98
end;
VER_PLATFORM_WIN32_NT:
PlatForm := 'WNT'; // Win NT/2000
end;
end;
begin
GetPlatForm;
if Pos(PlatForm, 'WNT') > 0 then
h := CreateFile(PChar('\\.\PhysicalDrive' + IntToStr(DrvIdx)), GENERIC_READ + GENERIC_WRITE,
FILE_SHARE_READ + FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
else if Pos(PlatForm, 'W95,W98') > 0 then
h := CreateFileA('\\.\Smartvsd', 0, 0, 0, CREATE_NEW, 0, 0)
else
Raise Exception.Create('Platform must be Win95, Win98, WinNT');
If h = 0 Then Exit;
ZeroMemory(@ParaIn, SizeOf(ParaIn));
ZeroMemory(@ParaOut, SizeOf(ParaOut));
with ParaIn do
begin
bDriveNumber := DrvIdx;
cBufferSize := 512;
With irDriveRegs do
begin
if (DrvIdx and 1) = 1 then
bDriveHeadReg := $B0
else
bDriveHeadReg := $A0;
bCommandReg := $EC;
bSectorCountReg := 1;
bSectorNumberReg := 1;
end;
end;
DeviceIoControl(h, $7C088, @ParaIn, SizeOf(ParaIn), @ParaOut, SizeOf(ParaOut), br, 0);
case HdInfoType of
HD_MODEL_NUMBER:
begin
st := 55;
ed := 94;
end;
HD_SERIAL_NUMBER:
begin
st := 21;
ed := 40;
end;
HD_FIRMWARE_REVISION:
begin
st := 47;
ed := 54;
end;
end;
i := st;
while i <= ed do
begin
if ParaOut.bBuffer[i + 1] = 0 then
break;
Sno := Sno + Chr(ParaOut.bBuffer[i + 1]);
if ParaOut.bBuffer[i] > 0 then
Sno := Sno + Chr(ParaOut.bBuffer[i]);
i := i + 2;
end;
CloseHandle(h);
Result := Trim(Sno);
end;
呼叫範例
Memo1.Lines.Add('型號:' + Get_HD_Info(0, HD_MODEL_NUMBER));
Memo1.Lines.Add('序號:' + Get_HD_Info(0, HD_SERIAL_NUMBER));
Memo1.Lines.Add('韌體版本:' + Get_HD_Info(0, HD_FIRMWARE_REVISION));