2008年7月27日 星期日

處理AVI所需的API - Part2

partial class AVIFileAPI
{

 // 獲得資料流檔頭資訊
 [DllImport("avifil32.dll")]
 extern internal static int AVIStreamInfo(IntPtr pavi, out AVISTREAMINFO psi, int lSize);

 [DllImport("avifil32.dll")]
 extern internal static int AVIStreamRelease(IntPtr pavi);

 // 得到一個取得Freame的物件
 [DllImport("avifil32.dll")]
 extern internal static IntPtr AVIStreamGetFrameOpen(IntPtr pavi, ref BITMAPINFOHEADER lpbiWanted);

 [DllImport("avifil32.dll")]
 extern internal static IntPtr AVIStreamGetFrameOpen(IntPtr pavi, int lpbiWanted);

 // 取得Frame的DIB
 [DllImport("avifil32.dll")]
 extern internal static IntPtr AVIStreamGetFrame(IntPtr pgf, int lPos);

 // 取得此資料流的總Sample數
 [DllImport("avifil32.dll")]
 extern internal static int AVIStreamLength(IntPtr pavi);

 [DllImport("avifil32.dll")]
 extern internal static int AVIStreamRead(IntPtr pavi, int lStart, int lSamples, IntPtr lpBuffer, int cbBuffer, out int plBytes, out int plSamples);

 // 讀取資料流指定位置的Frame的格式資訊
 [DllImport("avifil32.dll")]
 extern internal static int AVIStreamReadFormat(IntPtr pavi, int lPos, out BITMAPINFOHEADER lpFormat, out int lpcbFormat);

 [DllImport("avifil32.dll")]
 extern internal static uint AVIStreamGetFrameClose(IntPtr pget);

 // 取得此資料流的起始Sample編號
 [DllImport("avifil32.dll")]
 extern internal static int AVIStreamStart(IntPtr pavi);
}

處理AVI所需的API - Part1

partial class AVIFileAPI
{
 [DllImport("avifil32.dll")]

 extern internal static void AVIFileInit();

 [DllImport("avifil32.dll")]
 extern internal static void AVIFileExit();

 [DllImport("avifil32.dll")]
 extern internal static uint AVIFileInfo(IntPtr pfile, out AVIFILEINFO pfi, int size);

 [DllImport("avifil32.dll")]
 extern internal static uint AVIFileOpen(out IntPtr pfile, string szFile, FILEOPENMODE mode, IntPtr pclsidHandler);

 [DllImport("avifil32.dll")]
 extern internal static int AVIFileRelease(IntPtr pfile);

 [DllImport("avifil32.dll")]
 extern internal static uint AVIFileGetStream(IntPtr pfile, out IntPtr ppavi, uint fccType, int lParam);
}

取得資料型態的大小(所佔的記憶體)

使用c的方式
unsafe
{
int size = sizeof( 資料型態名稱 );
}

使用c#的方式
int size = Marshal.SizeOf( 物件名稱 );
or
int size = Marshal.SizeOf( typeof( 資料型態名稱 ) );

資料型態可以是類別或結構

處理AVI所需的結構

namespace AVIProcess
{
 partial class AVIFileAPI
 {
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  internal struct RECT
  {
   int left;
   int top;
   int right;
   int bottom;
  }

  /// 檔案開啟模式
  internal enum FILEOPENMODE : uint
  {
   OF_READ = 0x00000000,
   OF_WRITE = 0x00000001,
   OF_READWRITE = 0x00000002,
   OF_SHARE_COMPAT = 0x00000000,
   OF_SHARE_EXCLUSIVE = 0x00000010,
   OF_SHARE_DENY_WRITE = 0x00000020,
   OF_SHARE_DENY_READ = 0x00000030,
   OF_SHARE_DENY_NONE = 0x00000040,
   OF_PARSE = 0x00000100,
   OF_DELETE = 0x00000200,
   OF_VERIFY = 0x00000400,
   OF_CANCEL = 0x00000800,
   OF_CREATE = 0x00001000,
   OF_PROMPT = 0x00002000,
   OF_EXIST = 0x00004000,
   OF_REOPEN = 0x00008000
  }

  /// AVI檔案資訊
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  unsafe internal struct AVIFILEINFO
  {
   public uint dwMaxBytesPerSec;
   public uint dwFlags;
   public uint dwCaps;
   public uint dwStreams;
   public uint dwSuggestedBufferSize;
   public uint dwWidth;
   public uint dwHeight;
   public uint dwScale;
   public uint dwRate;
   public uint dwLength;
   public uint dwEditCount;
   public fixed char szFileType[64];
  }

  /// Bitmap檔頭資訊
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  internal struct BITMAPINFOHEADER
  {
   public uint biSize;
   public int biWidth;
   public int biHeight;
   public ushort biPlanes;
   public ushort biBitCount;
   public uint biCompression;
   public uint biSizeImage;
   public int biXPelsPerMeter;
   public int biYPelsPerMeter;
   public uint biClrUsed;
   public uint biClrImportant;
  }

  /// Bitmap檔案檔頭
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  internal struct BITMAPFILEHEADER
  {
   public UInt16 bfType;
   public uint bfSize;
   public UInt16 bfReserved1;
   public UInt16 bfReserved2;
   public uint bfOffBits;
  }

  /// 資料流資訊
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  unsafe internal struct AVISTREAMINFO
  {
   public uint fccType;
   public uint fccHandler;
   public uint dwFlags;
   public uint dwCaps;
   public UInt16 wPriority;
   public UInt16 wLanguage;
   public uint dwScale;
   public uint dwRate;
   public uint dwStart;
   public uint dwLength;
   public uint dwInitialFrames;
   public uint dwSuggestedBufferSize;
   public uint dwQuality;
   public uint dwSampleSize;
   RECT rcFrame;
   public uint dwEditCount;
   public uint dwFormatChangeCount;
   public fixed char szName[64];
  } 

  internal static uint mmioFOURCC(char c0, char c1, char c2, char c3)
  {
   return (uint)c0 | ((uint)c1) << 8 | ((uint)c2) << 16 | ((uint)c3) << 24;
  }

  internal static readonly uint streamtypeVIDEO = mmioFOURCC('v', 'i', 'd', 's');
  internal static readonly uint streamtypeAUDIO = mmioFOURCC('a', 'u', 'd', 's');
  internal static readonly uint streamtypeMIDI = mmioFOURCC('m', 'i', 'd', 's');
  internal static readonly uint streamtypeTEXT = mmioFOURCC('t', 'x', 't', 's');

  internal const int AVIGETFRAMEF_BESTDISPLAYFMT = 1;

 }
}

2008年7月23日 星期三

神奇的數字"4294967295"

今天在寫入資料庫的時候, 新增第一筆資料後就無法繼續下去
原來無法新增第二筆資料的原因為 id重複了
後來查看該筆資料, 發現該筆資料的id為4294967295
這就奇怪了, 第二筆資料在還未新增至資料庫前id並非4294967295
為何exception message顯示4294967295 key值重複
而且我的id是隨時間產生, 怎麼每次錯誤都是顯示 4294967295 key值重複
一開始我是抱持著這個想法, 到底我的id是在什麼時候被改變的呢?
在trace後發現在執行 command.ExecuteNonQuery() 前, id都是正常的尚未改變過
怎麼一執行到這行就發生exception了呢? 而且還指示 id為4294967295 key值重複
上網查了一下原來 4294967295 是 FFFFFFFF 也就是 4bytes, 而UINT型態剛好就是4bytes
這下子真相終於大了一個白
因為我的column type 設成INT, 而我的data是BIGINT, 所以~~~~~~~~~就是這樣!!

2008年7月16日 星期三

讓螢幕呈現Windows畫面關機時, 無法操作背景

要實現此效果
我們可以使用一個<DIV>物件
重點在於將此物件, 加上半透明背景, 並且放大至全畫面

需要設定的地方如下:

WIDTH:100%; //設定寬度
HEIGHT100%; //設定高度
POSITIONabsolute; //設定為"絕對位置"
LEFT0px; //設定X座標
TOP0px; //設定Y座標
BACKGROUND-COLOR#000000; //設定背景色
FILTERalpha(opacity=50); //半透明(for IE)
MOZ-OPACITY0.5; //半透明(for FireFox)
OPACITY0.5; //半透明(CSS 3標準)

<DIV> 與 <SPAN>

這兩個標籤的用途是將標籤內的東西,
如:文字、圖片、表格等 包成一個物件

可以把它想成是一個panel

不同之處在於
會將打包後的物件獨立於一個區域

例如:
原始碼:Hello <DIV> JIM </DIV> !!
顯示結果:
Hello
JIM
!!

原始碼:
Hello <SPAN> JIM </SPAN> !!
顯示結果:
Hello JIM !!

2008年7月15日 星期二

DataTable 合併

若要將兩個Schema相同的DataTable合併
可以使用DataTable.Merge() 方法

假設有兩DataTable 分別為 Table1 及 Table2
若要將 Table2 合併到 Table1, 使用方式如下:
Table1.Merge(Table2);

若要將 Table2 合併到 Table1, 但重複的資料列只保留一筆
則必須多設定Table1的PrimaryKey(主鍵)屬性, 使用方式如下
Table1.PrimaryKey = new DataColumn[ ] { Table1.Columns[ "primaryKeyColName" ] };
Table1.Merge(Table2);

2008年7月14日 星期一

DropDownList 的 DataSource 使用 SortedList

SortedList<object, object> sList = new SortedList<object, object>();
sList.Add("台北市", 1);
sList.Add("台北縣", 2);
sList.Add("桃園縣", 3);

DropDownList ddlCity = new DropDownList();

ddlCity.DataSource = sList ;
ddlCity.DataTextField = "Key";
ddlCity.DataValueField = "Value";
ddlCity.DataBind();

//因為sList不是一個資料表,
//所以無法賦予DataTextField 及 DataValueField 要對應的欄位名稱
//因此給予 Key 與 Value 字串
, 分別表示要顯示的內容 與 內容值

刪除List中的某些Item

要使用迴圈的方式刪除List中的某幾個Item時必須注意
迴圈中的index值應由最後面, 依序判斷至最前面
假設有一List如下:
List.Items[0] = "A";
List,Items[1] = "A";
List.Items[2] = "B";
List.Items[3] = "C";
若要將值為 "A" 的 Item 從 List 中移除,可以使用for迴圈來判斷
一般使用錯誤的方式如下:
for ( int index = 0; index <
List.Items.Count; index++ )
{

  if ( List.Items[index] == "A" )
    List.Items.RemoveAt ( index );
}
應注意的是,
當 index = 0 的時候, 會執行
List.Items.RemoveAt(index);
這時 List 的內容將會如下:
List,Items[0] = "A";
List.Items[1] = "B";
List.Items[2] = "C";

繼續在下一個迴圈,
當 index = 1 的時候, 我們看到此時
List.Items[index] 為 "B"
這表示第2個"A" 被跳過了, 想當然最後的結果是錯誤的.

因此我們應該將程式改為下面的方式:
for ( int index = List.Items.Count - 1; index > 0; index-- )
{
  if ( List.Items[index] == "A" )
    List.Items.RemoveAt ( index );
}

2008年7月11日 星期五

取得網路主機資訊

經由域名(like : www.google.com)
需要使用到兩個類別
第一個是, 使用 IPHostEntry 類別來存放主機資訊
第二個是, 使用 Dns 類別來取得主機資訊

使用方式如下:
IPHostEntry ipHost = Dns.Resolve("www.google.com"); (已過時)

IPHostEntry ipHost = Dns.GetHostEntry("www.google.com");

要注意的是, 使用的是域名不可加入協定
ex.
http://www.google.com
or
telnet://
ptt.cc
都是錯誤的用法

接下來可由 IPHostEntryAddressList 屬性來取得
,由DNS主機解析出來, 所有對應此網域的ip

IPAddress ipAddress = ipHost.AddressList[0]

接下來可由 IPHostEntryHostName 屬性來取得主機名稱
string hostName =
ipHost.HostName;

2008年7月10日 星期四

取得螢幕畫面

using System.Runtime.InteropServices;

[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int index);


//取得螢幕解析度(w:寬 , h:高)
int w = GetSystemMetrics(0);
int h = GetSystemMetrics(1);
//建立畫布
Bitmap bmp = new Bitmap(w, h);
Graphics
gh = Graphics .FromImage(bmp);
//取得螢幕畫面( 畫面將填入bmp中)
gh.CopyFromScreen(0, 0, 0, 0, new Size(w,h), CopyPixelOperation.SourceCopy);

取得螢幕解析度

using System.Runtime.InteropServices;

[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int index);


參數:
index : 0 表示取得寬度 , 1 表示取得高度