ラベル winapi の投稿を表示しています。 すべての投稿を表示
ラベル winapi の投稿を表示しています。 すべての投稿を表示

2009年3月28日土曜日

C#Win32APIの構造体を扱う

C#からWin32APIの構造体ここではRECTをとりあげますが、
他の構造体も同じように扱うことが出来ます。

直接C#のRectangleを使えたら。。便利なのに。
とは思いましたが、構造体のメモリ配置などの関係により、
直接Rectangleは使えません。

で、新しく構造体を定義して使うのですが、メモリ配置がネックになってきますので、
メモリ配置(レイアウト)を決める属性をつけて構造体を定義します。

詳しくはMSDNを参照のこと。
■LayoutKind 列挙体

http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.layoutkind(VS.71).aspx


構造体の定義が出来れば後はただ使うだけっと。
コードは以下のようになります。
----------------
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern void GetWindowRect(IntPtr hWnd, out RECT wndRect);
----------------


こんな感じ。

.

2009年3月23日月曜日

C#でアクティブウィンドウの取得

アクティブウィンドウを取得する方法
アクティブプロセスからウィンドウハンドルを取得する。
直接アクティブウィンドウを取得する.NET FrameWorkのクラス(関数)は無いみたい。

Win32APIを使っての取得方法を紹介。
以下のクラス(関数)を使ってアクティブプロセスを取得し、
取得したプロセスのProcess.MainWindowHandle でウィンドウハンドルを取得します。

---------------
/// Win32API の extern 宣言クラス
public class WinAPI {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
}

public class sample {
///


/// アクティブなプロセスを取得する
///

/// アクティブプロセス
public static Process GetActiveProcess()
{
// アクティブなウィンドウハンドルの取得
IntPtr hWnd = WinAPI.GetForegroundWindow();
int id;
// ウィンドウハンドルからプロセスIDを取得
WinAPI.GetWindowThreadProcessId(hWnd, out id);
Process process = Process.GetProcessById(id)
return process;
}
}
---------------

取得したウィンドウハンドルとWin32APIを使って、
様々なプロセスに対しての操作が可能となります。

.

2009年3月22日日曜日

C#でWin32APIを呼び出す

方法はDLLをインポートして、メソッドを extern 宣言するだけ。
引数や戻り値はC#の型にあわせればOK。
あわない型であれば、コンパイル時にエラーが出ます。

MoveWindow 関数は以下のように宣言しました。

-------------
public class Test {
[DllImport("user32.dll")]
public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint);
}
-------------

気をつけないといけないのは。。
Win32で使われている構造体ですね。
これらについてはまた書きます。

.

2007年7月26日木曜日

実行ファイルパス取得(WIN32)

これも紹介しとこ。
WinMainからやと実行ファイルパスを取得する方法が
よくわからんかって調べたのでメモ。
※gccでコンパイルして試しました。

まずは main 関数と同じように引数で渡ってこないかを考え
CmdLine の中身を調べて見たが・・・
CmdLine の中にはコマンドライン引数しか入っていなかったのでこれはだめ。

で、MSDNを探して見つけた。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdllpro/html/_win32_getmodulefilename.asp
GetModuleFileName 関数
これで実行ファイルの絶対パスが取得できる。

__argv というグローバル変数もあるみたいで
これやと実行ファイル名が取得できた。

以下に使い方を示す。
--------
#include <stdio.h>
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR CmdLine,
int CmdShow)
{
char buff[256] = {0};
printf("CmdLine = [%s]\n", CmdLine);
// この関数で buff に実行ファイルの絶対パスを取得できる。
GetModuleFileName(hInstance, buff, 256);
printf("[%s]\n",buff);

printf("[%s]\n",__argv[0]);
return 0;
}
--------

実行ファイルパスは取得できると何かと便利ですよね。
バックアップファイルの保存だの。
設定ファイルの読み込みだの。
使い方いろいろ!
変わった使い方してる人いないかな~?

.

2007年6月20日水曜日

ウィンドウの生成

ウィンドウを作る手順。
1、WNDCLASSEX構造体にデータを設定する
2、RegisterClassEx関数でクラスを登録する
3、CreateWindowEx関数でウィンドウを生成

CreateWindowEx関数でRegisterClassEx関数で登録した
WNDCLASSEX構造体の情報をもとにウィンドウを生成します

CreateWindowEx関数
http://msdn2.microsoft.com/en-us/library/aa930455.aspx

HWND CreateWindowEx( //戻り値 ウィンドウハンドル
DWORD dwExStyle, // ウィンドウの拡張スタイル
LPCTSTR lpClassName, // 生成するウィンドウクラスの名前
LPCTSTR lpWindowName, // ウィンドウの名前(タイトルバーに表示されます)
DWORD dwStyle, // ウィンドウスタイル
int x, // ウィンドウを表示する X座標
int y, // ウィンドウを表示する Y座標
int nWidth, // ウィンドウの幅
int nHeight, // ウィンドウの高さ
HWND hWndParent, // 親ウィンドウハンドル
HMENU hMenu, // メニューハンドル
HINSTANCE hInstance, // 実行exeのインスタンスハンドル
LPVOID lpParam // 生成時のメッセージで渡す引数
);

CreateWindowEx関数のリンク先に
拡張スタイルとスタイルの渡すべき値(Define定義されているもの)の一覧が
載っていますのでそれを参考にしてスタイルを指定します

次回簡単な例でものっけよ

2007年6月14日木曜日

ウィンドウクラスの登録

ウィンドウを作る手順。
1、WNDCLASSEX構造体にデータを設定する
2、RegisterClassEx関数でクラスを登録する
3、CreateWindowEx関数でウィンドウを生成

今回は
2、RegisterClassEx関数でクラスを登録する
です

RegisterClassEx関数について
http://msdn2.microsoft.com/en-us/library/ms633587.aspx
ATOM RegisterClassEx(
CONST WNDCLASSEX *lpwcx // ウィンドウクラスのポインタ
);
RegisterClassExに登録する前に WNDCLASSEX の各値を設定しておかないと
失敗する。戻り値に0(ゼロ)が戻ってきた時が失敗した時である
その場合は WNDCLASSEX で設定したウィンドウを生成することが出来ない

RegisterClassExで登録した WNDCLASSEX のデータは
アプリケーションを終了するまで削除されない

よって一度登録しておくと、登録したWNDCLASSEXのデータで
何度もウィンドウを生成することができる

完全なメモになってしまったや
まっいいかw

2007年6月10日日曜日

ウィンドウを生成するのに必要な構造体(WNDCLASSEX)

ウィンドウを作る手順。
1、WNDCLASSEX構造体にデータを設定する
2、RegisterClassEx関数でクラスを登録する
3、CreateWindowEx関数でウィンドウを生成
こんだけw

今回は「1、WNDCLASSEX構造体にデータを設定する」の構造体について知る
MSDNを参照(http://msdn2.microsoft.com/en-us/library/ms633577.aspx)

英語で書いてあるのを訳せば終わりなんやけどね~。
ちょこっと記述してみた。
typedef struct {
UINT cbSize; //クラスのサイズを設定WNDCLASSとを識別するために必要
UINT style; // ウィンドウのスタイルを設定
WNDPROC lpfnWndProc; //メッセージを処理する関数を登録する
int cbClsExtra; // この構造体に付加する領域のbyteサイズ
int cbWndExtra; // ウィンドウのインスタンスに付加する領域のbyteサイズ
HINSTANCE hInstance; // 実行ファイルのインスタンスハンドル
HICON hIcon; // ウィンドウのアイコンのハンドル
HCURSOR hCursor; // ウィンドウ内のマウスカーソルのハンドル
HBRUSH hbrBackground; // ウィンドウ領域の背景色を塗りつぶすブラシのハンドル
LPCTSTR lpszMenuName; // ウィンドウに表示するメニューの名前
LPCTSTR lpszClassName; // ウィンドクラスの名前、生成する時に使う
HICON hIconSm; // 小さいアイコン
} WNDCLASSEX

ん~ハンドルが沢山あるな…
おいおい詳しくわかってくるやろ

2007年6月8日金曜日

WinMainのWINAPIというおまじないについて

前回の投稿(http://mzs184.blogspot.com/2007/06/mainwinmain.html)で

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow);

のWINAPIってなんなんやろ~って疑問として残ってましたが、
windef.h内で以下のように定義されていました。

#define WINAPI __stdcall

__stdcallってなんやねん!って調べてたら。
関数の呼び出し規約とかいうものらしい

ここがすごいわかりやすかったので紹介
http://arton.no-ip.info/collabo/backyard/?StdDeclCDecl
-----紹介したサイトの抜粋です
__stdcallは、WIN32 APIの呼び出し規約で、スタックの解放を呼ばれた側が行い(したがって、varargは使用不可)、__cdeclは、スタックの解放を呼ぶ側が行う(したがって、varargを使用可能)。
----
実際にアセンブリコードとの混合モードで解説してあるので
すんごいわかりやすかった!

WINAPIというおまじないはこれで解決っと

2007年6月5日火曜日

mainじゃなくてWinMainなんやね!

仕事で.NET2.0を使ってるんですが、
もうちょと詳しくウィンドウアプリケーションを知っておこうと
C言語にてwindowを作ってみる。
もちろんコンパイラはMinGWのgccコンパイラです。
過去の日記でインストールした時にwinapi関連のライブラリも
インストールできているのでそのまま使います。

で…ネットを検索しまくって
こんなヘッダーをインクルードして。
#include <windows.h>

こんな関数がエントリーポイントになっていると知る。
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow);

そして、意味不明な大文字の型が…
WINAPI 良くわかりません。とりあえずおまじないと思って書いておく
HINSTANCE:void*をtypedefしたやつやった。
     「インスタンスハンドル」やねんて
PSTR:strっていうぐらいやから文字列の型「wchar*」or「char*」をtypedefしたもの
   UNICODEを使えるか使えないかで場合分けしてある

んで各引数の説明
HINSTANCE hInstance
:実行したプログラムを識別するためのもの

HINSTANCE hPrevInstance
:すんごい昔に多重起動を確認するために使われていた今はNULLしか入ってこない

PSTR szCmdLine
:コマンドラインで実行した時の引数、今までも同じものあったからこれは大丈夫かな

int iCmdShow
:ウィンドウの初期表示方法です ウィンドウを生成する時に使うそうな…


以下のコードを書いて簡単に呼び出してみた
メッセージボックスが表示されておしまい。
-------
#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
MessageBox (NULL, TEXT("text"), TEXT("caption"), MB_OK);
return 0;
}

-------

TEXT()はマクロでUNICODE対応の場合は文字列の先頭に「L」を付ける

例TEXT("text")
 ⇒UNICODE対応 ⇒ L"text"
 ⇒UNICODE非対応 ⇒ "text"

まだウィンドウは作成できず…

ラベル