本來是想實現控制台程式運行時自動全屏,但是只找到VC下的實現方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347)。
其中要使用兩個未公開的Win32 API函數來存取控制台視窗,這就需要使用動態調用的方法,動態調用中使用的Windows API函數主要有三個,即:Loadlibrary,GetProcAddress和Freelibrary。步驟如下:
1. Loadlibrary: 裝載指定DLL動態庫
2. GetProcAddress:獲得函數的入口地址
3. Freelibrary: 從記憶體中卸載動態庫
但是C#中是沒有函數指標,無法直接使用GetProcAddress返回的入口地址。後來找到資料,其實.NET 2.0新增了Marshal.GetDelegateForFunctionPointer 方法可以滿足這個要求,MSDN裡的解釋是:將非託管函數指標轉換為委託。
後面的事就簡單啦,我把它編成了一個類來方便調用。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace feiyun0112.cnblogs.com
{
public class DllInvoke
{
Win API#region Win API
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
#endregion
private IntPtr hLib;
public DllInvoke(String DLLPath)
{
hLib = LoadLibrary(DLLPath);
}
~DllInvoke()
{
FreeLibrary(hLib);
}
//將要執行的函數轉換為委託
public Delegate Invoke (string APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}
}
}
下面是使用的例子:using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using feiyun0112.cnblogs.com;
namespace ConsoleApplication1
{
class Program
{
Win API#region Win API
[DllImport("kernel32.dll")]
public static extern IntPtr GetStdHandle(int nStdHandle);
const int STD_OUTPUT_HANDLE = -11;
#endregion
public delegate bool SetConsoleDisplayMode(IntPtr hOut, int dwNewMode, out int lpdwOldMode);
static void Main(string[] args)
{
DllInvoke dll = new DllInvoke("kernel32.dll");
int dwOldMode;
//標準輸出控制代碼
IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE);
//調用Win API,設定螢幕最大化
SetConsoleDisplayMode s = (SetConsoleDisplayMode)dll.Invoke("SetConsoleDisplayMode", typeof(SetConsoleDisplayMode));
s(hOut, 1, out dwOldMode);
Console.WriteLine("********************Full Screen Mode********************");
Console.ReadLine();
}
}
}