ウィンドウの作成

Windows APIによるウィンドウの作成例です。

プログラムを実行すると、下図のようなウィンドウが生成され、演奏のボタンをクリックするとファイル選択用のダイアログが開き、MIDIの再生が行われます。

midi window

コンパイル時のオプションは、

 gcc -o list_60 list_60.cpp -lwinmm -lgdi32 -lcomdlg32 

となります。それぞれ、MCI、ウィンドウの背景色を設定するためのブラシの準備(GetStockObject(WHITE_BRUSH))、ファイル選択用のダイアログ(GetOpenFileName(&ofn))に必要となります。

ウィンドウの作成(list_60.c)
//-----------------------------------------------------------------
// list_60.c
//     MCI: MIDI演奏
//              Last Update: <2004/11/19 03:26:26 murakami>
//-----------------------------------------------------------------
#include <windows.h>
#include <wingdi.h>   // ブラシの取得(ウィンドウ色)
#include <mmsystem.h> // MCIデバイス

// lib: libwinmm.a, libgdi32.a, lcomdlg32.a が必要
//       (MCI)       (Brush)     (FileDlg)

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void playMidi(char *);
void stopMidi(void);

HINSTANCE hInst;
HWND hwnd,hwPlayB,hwStopB;
BOOL play;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
    MSG  msg;
    WNDCLASSEX  wndclass ;(HBRUSH)GetStockObject(WHITE_BRUSH);
    
    hInst=hInstance; // プロセスのハンドルを保存
    wndclass.cbSize        = sizeof(wndclass);
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = "MIDI Play Window";
    wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION);

    RegisterClassEx (&wndclass);
    hwnd = CreateWindow ("MIDI Play Window",
                         "MIDI演奏",
                         WS_OVERLAPPEDWINDOW,
                         64,64,
                         240,80,
                         NULL,
                         NULL,
                         hInstance,
                         NULL);
    
    DragAcceptFiles(hwnd,TRUE); // ドラッグ&ドロップ受入
    ShowWindow (hwnd,iCmdShow);      // ウインドウを表示
    UpdateWindow (hwnd);             // 再描画
    while (GetMessage (&msg,NULL,0,0)) { // メッセージループ
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static OPENFILENAME ofn;
    static char szFn[256],szFt[256],str[280];
    HDROP hDrop;

    ofn.lStructSize=sizeof(OPENFILENAME); // ファイルを開くダイアログ設定
    ofn.hwndOwner=hwnd;
    ofn.hInstance=NULL;
    ofn.lpstrFilter= "MIDI(*.mid)\0*.mid\0すべてのファイル(*.*)\0*.*\0\0";
    ofn.lpstrCustomFilter=NULL;
    ofn.nMaxCustFilter=0;
    ofn.nFilterIndex=1;      // フィルターの初期位置
    ofn.lpstrFile=szFn;      // ファイル名用文字列バッファ
    ofn.nMaxFile=255;        // 文字列バッファのサイズ
    ofn.lpstrFileTitle=szFt; // タイトル用文字列バッファ
    ofn.nMaxFileTitle=255;   // 文字列バッファのサイズ
    ofn.lpstrInitialDir=NULL;
    ofn.lpstrTitle="MIDIファイル";
    ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    ofn.nFileOffset=0;
    ofn.nFileExtension=0;
    ofn.lpstrDefExt=NULL;
    ofn.lCustData=0;
    ofn.lpfnHook=NULL;
    ofn.lpTemplateName=NULL;
    
    switch (iMsg) {
    case WM_CREATE:
        hwPlayB=CreateWindow("Button","演奏", // ボタン作成
                             WS_CHILD | WS_VISIBLE,20,10,80,32,hwnd,
                             (HMENU)0,hInst,NULL);
        hwStopB=CreateWindow("Button","停止",
                             WS_CHILD | WS_VISIBLE,130,10,80,32,hwnd,
                             (HMENU)1,hInst,NULL);
        play=FALSE; // 演奏フラグリセット
        EnableWindow(hwStopB,FALSE); // 中止ボタン無効
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case 0: // Playボタン
            // ファイルを選択
            if(!GetOpenFileName(&ofn)) return 0;
            playMidi(szFn); // 演奏開始
            break;
        case 1: // Stopボタン
            if(play) stopMidi();
            break;
        }
        break;
        return 0;
    case WM_DROPFILES: // ファイルがドロップされた時の処理
        hDrop=(HDROP)wParam; // HDROPを取得
        DragQueryFile(hDrop,0,szFn,256); // ファイル名を取得
        DragFinish(hDrop); // 終了処理
        playMidi(szFn);    // 演奏開始
        return 0;
    case MM_MCINOTIFY: // 演奏終了時の処理
        if(!play) return 0;
        // 最初に巻き戻して再度演奏開始
        mciSendString("seek music to start",NULL,0,hwnd);
        mciSendString("play music NOTIFY",NULL,0,hwnd);
        return 0;
    case WM_DESTROY :
        // 演奏中ならデバイス開放
        if(play) stopMidi(); 
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}

void playMidi(char *fn) {
    char cmd[280],res[128];
    if(play) return; // すでに演奏中なら戻る
    lstrcpy(cmd,"open "); // デバイスオープン
    lstrcat(cmd,fn);
    lstrcat(cmd," alias music");
    mciSendString(cmd,NULL,0,NULL);
    mciGetErrorString(mciSendString("play music NOTIFY",NULL,0,hwnd),res,128);
    play=TRUE; // 演奏フラグセット
    EnableWindow(hwPlayB,FALSE); // プレイボタン無効
    EnableWindow(hwStopB,TRUE);  // 中止ボタン有効
}

void stopMidi(void) { // 演奏終了とデバイス開放
    play=FALSE;       // 演奏フラグリセット
    mciSendString("stop music",NULL,0,NULL);
    mciSendString("close music",NULL,0,NULL);
    EnableWindow(hwPlayB,TRUE);  // プレイボタン有効
    EnableWindow(hwStopB,FALSE); // 中止ボタン無効
}
inserted by FC2 system