ページ 11

C++でWindowsAPIを使いたい

Posted: 2007年6月13日(水) 18:30
by ひろ
久しぶりにお世話になろうと思います。
3ヶ月以上来ていなかったので、ポイントもリセットされてしまったみたいですね。。。

早速ですが

WindowsAPIで作成したウインドウでコマンドボタンを押したら
ディレクトリ配下のファイルの一覧がテキストで表示される

というプログラムをC++のクラスやコンストラクタを使って作成しなければ
ならないのですが、参考になるようなHPなどを教えてください。

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月13日(水) 18:52
by YuO
何が解らないのですか?
WinAPIの知識とC++の知識は基本的に直交しているはずなので,どっちも理解していれば組み合わせるだけですが。

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月13日(水) 18:56
by asd
まずは検索してみたのでしょうか?
分からないことがあったらまずは検索してみるといいですよ^^
http://www.google.co.jp/search?hl=ja&q= ... %B4%A2&lr=

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月14日(木) 09:20
by ひろ
ありがとうございます。

>YuOさん
どっちの知識も覚えたばかりで、組み合わせ方がわかりません。

>asd
検索してみていろいろなサイトを見たのですが、
C++とAPIの組み合わせについて載っているサイトが見つかりませんでした。

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月14日(木) 09:46
by バグ
画像を拝見した限りではMFCをお使いみたいですね?
それでしたら、CFileFindクラスをMSDNで検索してみると良いかもしれません(^-^)

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月14日(木) 09:58
by asd
> 検索してみていろいろなサイトを見たのですが、
> C++とAPIの組み合わせについて載っているサイトが見つかりませんでした。

コピペしてそのまま動くサンプルが転がっているとは限りませんが、
C/C++でWindowsAPI(Win32API)を使うサンプルならいくつもあるみたいです。

またWindowsAPIだけで検索しても大体C/C++で書かれているので参考になると思います。

まずは具体的にどのAPIが使えそうなのか探しませんか?
ドンピシャリなサンプルがないからと諦めていたら勉強にならない気がします。
作らなければならない状況にあるのならまずはいろいろ探して作ってみませんか?

参考になればどうぞ^^
WindowsAPIによるVisualC++入門
http://www.st.chukyo-u.ac.jp/h104049/VC_0/VC_0.html

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月18日(月) 13:35
by ひろ
バグさん、asdさん、ありがとうございました。
いろいろ調べて、とりあえずC言語で作ってみたのですが、
WM_COMMANDのHWNDに値が継承できません。
何が問題なのでしょうか?

まだ開始ボタンの動作は入れてないのですが、
ラジオボタンにチェックを入れるとチェックボタンを無効にしたり
できるはずなのですが・・・

あと何かアドバイスがあればお願いします。

#include <windows.h>
#include "hdr\Primitive.h"

#define cID_StartBtn 0
#define cID_EndBtn 1
#define cID_DisplayChk 2
#define cID_DaySizeChk 3
#define cID_PassEdt 4
#define cID_TreeRdo 5
#define cID_ListRdo 6

// -----------------------------------------------------------------
// ウィンドウ・クラスの登録
// -----------------------------------------------------------------
BOOL InitApp(HINSTANCE hInstance, WNDPROC fnWndProc){
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = fnWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL , IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE+1;
wc.lpszMenuName = NULL;
wc.lpszClassName = "TreeClass";
return (RegisterClass(&wc));
}

// -----------------------------------------------------------------
// ウィンドウの生成
// -----------------------------------------------------------------
DEF_BOOL InitInstance(HINSTANCE hInstance, int inCmdShow){
HWND hwnd;
hwnd = CreateWindow("TreeClass",
"ディレクトリ表示ツール(miyata)",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 600, 250, NULL, NULL,
hInstance, NULL);

return TRUE;
}

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月18日(月) 13:36
by ひろ
ソースの続きです
よろしくお願いします

// -----------------------------------------------------------------
// ウィンドウプロシージャ
// -----------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp){
HWND hbtnENTER, hbtnEND, hedtDIR, hchkSIZE,
hchkFILE, hrdoTREE, hrdoLIST;

HANDLE hFILE = NULL, hFind = NULL;
HINSTANCE hInst;
// -------------------------------------------------------------
// hInstanceの情報を取得
// -------------------------------------------------------------
hInst = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);

switch (msg) {
// ---------------------------------------------------------
// 子ウィンドウの生成
// ---------------------------------------------------------
case WM_CREATE:
hbtnENTER = CreateWindow("BUTTON", "実行",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
400, 180, 80, 25,
hwnd, (HMENU)cID_StartBtn, hInst, NULL);
hbtnEND = CreateWindow("BUTTON", "終了",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
490, 180, 80, 25,
hwnd, (HMENU)cID_EndBtn, hInst, NULL);
hchkFILE = CreateWindow("BUTTON", "ファイルを表示する",
WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX ,
250, 120, 170, 20,
hwnd, (HMENU)cID_DisplayChk, hInst, NULL);
hchkSIZE = CreateWindow("BUTTON", "ファイルの日付とサイズを表示する",
WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX ,
250, 140, 275, 20,
hwnd, (HMENU)cID_DaySizeChk, hInst, NULL);
hedtDIR = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "C:\\Program Files",
WS_CHILD | WS_VISIBLE |WS_BORDER,
170, 20, 400, 23,
hwnd, (HMENU)cID_PassEdt, hInst, NULL);
CreateWindow("STATIC", "ディレクトリ パス",
WS_CHILD | WS_VISIBLE,
20, 20, 150, 20,
hwnd, NULL, hInst, NULL);
CreateWindow("STATIC", "オプション:",
WS_CHILD | WS_VISIBLE,
200, 90, 150, 20,
hwnd, NULL, hInst, NULL);
CreateWindow("BUTTON", "表示モード",
WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
15, 90, 170, 80,
hwnd, NULL, hInst, NULL);
hrdoTREE = CreateWindow("BUTTON", "ツリー構造",
WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP ,
30, 120, 100, 20,
hwnd, (HMENU)cID_TreeRdo, hInst, NULL);
hrdoLIST = CreateWindow("BUTTON", "ファイルリスト",
WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
30, 140, 130, 20,
hwnd, (HMENU)cID_ListRdo, hInst, NULL);
SendMessage(hrdoTREE, BM_CLICK, 0, 0);
break;

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月18日(月) 13:37
by ひろ
もうひとつ続きです

// ---------------------------------------------------------
// イベント取得
// ---------------------------------------------------------
case WM_COMMAND:
switch (LOWORD(wp)){
case cID_ListRdo:
if(SendMessage(hrdoLIST, BM_GETCHECK, 0, 0) == DEF_TRUE){
SendMessage(hchkFILE, BM_SETCHECK, BST_CHECKED, 0);
EnableWindow(hchkFILE, DEF_FALSE);
EnableWindow(hchkSIZE, DEF_TRUE);
}
break;
case cID_TreeRdo:
if(SendMessage(hrdoTREE, BM_GETCHECK, 0, 0) == DEF_TRUE){
SendMessage(hchkSIZE, BM_SETCHECK, BST_UNCHECKED, 0);
EnableWindow(hchkFILE, DEF_TRUE);
EnableWindow(hchkSIZE, DEF_FALSE);
}
break;
case cID_StartBtn:
DWORD dwWriteSize;
WIN32_FIND_DATA fd;
DEF_INT8 lachDirPass[400];
DEF_INT8 lachSearchPass[400];
memset(lachDirPass, '\0', strlen(lachDirPass));
memset(lachSearchPass, '\0', strlen(lachSearchPass));
if(GetWindowText(hedtDIR, lachDirPass, strlen(lachDirPass)) == 0){
MessageBox(NULL, "ディレクトリパスの取得に失敗しました",
"エラー", MB_OK);
SendMessage(hwnd, BM_CLICK, 0, 0L);
}

memcpy(lachSearchPass + strlen(lachSearchPass), "\\*", 3);

hFILE = CreateFile(
"tree.txt", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFILE == INVALID_HANDLE_VALUE) {
MessageBox(NULL, "ファイルを作成できませんでした",
"エラー", MB_OK);
SendMessage(hwnd, BM_CLICK, 0, 0L);
}
if(SendMessage(hrdoTREE, BM_GETCHECK, 0, 0) == DEF_TRUE){
WriteFile(hFILE, lachDirPass, strlen(lachDirPass), &dwWriteSize, NULL);
WriteFile(hFILE, lachDirPass, strlen(lachDirPass), &dwWriteSize, NULL);
if(SendMessage(hchkSIZE, BM_GETCHECK, 0, 0) == DEF_TRUE){
}
else{
}
}
else{
if(SendMessage(hchkFILE, BM_GETCHECK, 0, 0) == DEF_TRUE){
}
else{
}
}
break;
case cID_EndBtn:
SendMessage(hwnd, WM_CLOSE, 0, 0L);
break;

}
case WM_PAINT: break;

case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wp, lp);
}

DEF_INT32 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, int inCmdShow ) {
MSG msg;

if(!InitApp(hInstance, WndProc))
return FALSE;
if(!InitInstance(hInstance, inCmdShow))
return FALSE;
while(GetMessage(&msg, NULL, NULL, NULL)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月18日(月) 13:41
by ひろ
すみません。
で囲むの忘れてました。。。

Re:C++でWindowsAPIを使いたい

Posted: 2007年6月18日(月) 14:29
by YuO
> いろいろ調べて、とりあえずC言語で作ってみたのですが、
> WM_COMMANDのHWNDに値が継承できません。
> 何が問題なのでしょうか?

えーっと,継承?

hbtnENTERとかの値が残っていないというのであれば,当たり前の話です。
変数の寿命について調べてみてください。
単に,WM_CREATEの時のhbtnENTERとWM_COMMANDの時のhbtnENTERは名前が同じだけで,別のオブジェクトですよ。

FindWindowで毎回探すか,SetProp/GetPropとかを使ってデータを保存しておくか,などの対策をする必要があります。
# staticはオブジェクト指向へ持って行くのにあまりにもかけ離れると思ったので除外。

Re:C++でWindowsAPIを使いたい

Posted: 2007年7月03日(火) 11:28
by ひろ
お礼を入れるのを忘れてました(^^;)

おかげさまで解決することができました!
ありがとうございます。