この記事の対象者
この記事は、私がC ++プログラミングの初心者で、偶然または意志によりWinAPIを学ぶことにしたのと同じことを扱っています。
すぐに警告したい:
私はC ++やWinAPIの第一人者のふりをしません。
私はただ学習しているので、WinAPIの機能とメカニズムを簡単に学習できるようにするいくつかの例とヒントをここに示したいと思います。
この記事では、クラスを作成し、さまざまな演算子をオーバーロードできるようにC ++について十分に学習していること、およびクラス内のメカニズムの一部を既に「隠している」ことを前提としています。
コンソールの作成と使用
Win32アプリケーションをデバッグするため、または単に内部でそれがどのように発生するかを確認するために、私は常にコンソールを使用します。
コンソールアプリケーションではなくGUIアプリケーションを作成しているため、コンソールは接続しません。 インターネットの腸でそれを呼び出すために、このコードが見つかりました
if (AllocConsole())
{
int hCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), 4);
*stdout = *(::_fdopen(hCrt, "w"));
::setvbuf(stdout, NULL, _IONBF, 0);
*stderr = *(::_fdopen(hCrt, "w"));
::setvbuf(stderr, NULL, _IONBF, 0);
std::ios::sync_with_stdio();
}
. :
void CreateConsole()
{
if (AllocConsole())
{
int hCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), 4);
*stdout = *(::_fdopen(hCrt, "w"));
::setvbuf(stdout, NULL, _IONBF, 0);
*stderr = *(::_fdopen(hCrt, "w"));
::setvbuf(stderr, NULL, _IONBF, 0);
std::ios::sync_with_stdio();
}
呼び出されたコンソールは出力モードでのみ機能し、コンソールアプリケーションと同じように機能します。 通常どおり情報を表示します-cout / wcout。
このコードを機能させるには、次のファイルをプロジェクトに含める必要があります。
#include <fcntl.h>
#include #include <io.h>
また、グローバル名前空間にstd名前空間を含めます。
名前空間stdを使用します。
もちろん、これを行いたくない場合は、その中にあるすべてのエンティティにstd ::を追加するだけです。
出力および属性のオブジェクトの継承。 操作
「ウィンドウ」自体を作成して学習するとき、コンソールに何らかの値を表示する必要が常にありました。
例:
GetClientRect関数を使用してウィンドウのクライアント領域のサイズを取得します。GetClientRect関数では、RECT構造体のオブジェクトのアドレスをパラメーターとして渡して、このオブジェクトにデータを入力します。 受信したクライアント領域のサイズを知る必要がある場合は、すでに接続されているコンソールに出力することができます
cout<<rect.right<<endl<<rect.bottom<<endl;
しかし、毎回それを行うこと(特にそのようなことを頻繁に行う必要がある場合)は非常に不便です。
ここでは、継承が助けになります。
RECT構造からオープンに継承するクラスを作成し、出力演算子<<を必要に応じてオーバーロードします。
例:
class newrect:public RECT
{
public:
friend ostream& operator<<(ostream &strm,newrect &rect)
{
strm<<"Prtint RECT object:\n";
strm<<rect.right<<endl<<rect.bottom<<endl;
return strm;
}
};
オブジェクトをcout / wcoutで印刷するだけです:
cout<<nrect;
また、便利な形式で、必要に応じてすべてが表示されます。
必要な演算子を使用することもできます。
たとえば、構造を比較または割り当てる必要がある場合(同じRECTまたはPOINTとしましょう)-演算子==()および演算子=()をそれぞれオーバーロードします。
ウィンドウサイズなどをすばやく比較するために、より小さい演算子<を実装する場合 オーバーロード演算子<()。
そのため、ほぼすべての構造で、最も重要なこととして、RECT構造の通常のオブジェクトで機能するすべての関数は、その子孫でも同様に機能すると思います。
また、このすべての美しさを別のインクルードファイルに取り出し、必要に応じて使用することもお勧めします。
自分のクラス
他の人がどうするかはわかりませんが、完全に環境に優しいので、勉強した機能ごとに、または本の章/章ごとに新しいプロジェクトを作成して、すべてが棚にあり、いつでも戻って必要な瞬間をリフレッシュできるようにしました。
WinAPIでは、単純なウィンドウを作成する場合でも、3番目または4番目のプロジェクトの後、クラス構造を入力して登録し、簡単なウィンドウプロシージャを記述する必要があるので、私はまだC ++で書いていたことを思い出しました。
その結果、すべてを単純なクラスに隠しました。 ウィンドウハンドル、その名前、クラス名、ウィンドウプロシージャアドレス、ウィンドウクラス(WNDCLASS)はすべて、クラスのプライベートセクションに隠されています。
それらを取得するには、次のような単純なGetメソッドを記述するだけで十分です。
HWND GetHWND()
LPCTSTR GetClsName()など
ウィンドウクラスの入力と登録、ウィンドウ自体の作成と表示は、コンストラクターで行われます。
便宜上、コンストラクタをオーバーロードし、個別のプライベートクラス関数でウィンドウクラスを非表示にして入力し、各コンストラクタを呼び出すことができます。 オーバーロードの利便性は、非常に単純なウィンドウを作成する必要がある場合があり、2つのパラメーター(ウィンドウの名前とアプリケーションインスタンス)を使用してコンストラクターを呼び出すことです。
また、デフォルトのウィンドウプロシージャやその他の特定のスタイルではなく、特別なサイズのウィンドウを作成する必要がある場合は、関連するパラメーターを使用してコンストラクターを呼び出します。
このクラスは、IDEのincludeフォルダーにある個別に含まれるファイルで定義されています。
このクラスのテンプレート:
class BaseWindow
{
WNDCLASSEX _wcex;
TCHAR _className[30];
TCHAR _windowName[40];
HWND _hwnd;
bool _WindowCreation();
public:
BaseWindow(LPCTSTR windowName,HINSTANCE hInstance,DWORD style,UINT x,UINT y,UINT height,UINT width);
BaseWIndow(LPCTSTR windowName,HINSTANCE hInstance);
const HWND GetHWND()const{return HWND;}
LPCTSTR GetWndName()const{return _windowName;}
};
そのようなクラスを慎重に考えて書いたら、人生を楽にし、毎回同じことを書くよりも多くの時間をトレーニングとスキルの磨きに費やします。 さらに、このようなクラスを自分で作成し、必要に応じて補足することは非常に便利です。
PS
説明されていることはすべて以下の場合に当てはまります。
プラットフォーム-Windows 7 32ビット
IDE-Visual Studio 2010
誰かがこれらのヒントで笑いと皮肉を引き起こすかもしれませんが、それでも、私たちはかつて幾分新参者/インターン/ジュニアアミでした。
投稿を理解して処理するようお願いします。 建設的な批判は大歓迎です。