バグ の日記

Win32APIのConsoleアプリ用Class Ver1.2

パーマリンク by バグ on 2013年10月17日(木) 14:05

毎回、探すの面倒なのでここに置かせてもらおう。
一応、VisualStudioとBCCの両方で動作する・・・はず。

※イベント処理を追加してちょっとだけバージョンアップ

<< Console.h >>
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma once
#include <windows.h>
 
namespace ConsoleColor
{
    static CONST WORD Black         = 0x0000;       // 黒
    static CONST WORD DarkBlue      = 0x0001;       // 暗い青
    static CONST WORD DarkGreen     = 0x0002;       // 暗い緑
    static CONST WORD DarkCyan      = 0x0003;       // 暗い水
    static CONST WORD DarkRed       = 0x0004;       // 暗い赤
    static CONST WORD DarkMagenta   = 0x0005;       // 暗い紫
    static CONST WORD DarkYellow    = 0x0006;       // 暗い黄
    static CONST WORD Gray          = 0x0007;       // 灰
    static CONST WORD DarkGray      = 0x0008;       // 暗い灰
    static CONST WORD Blue          = 0x0009;       // 青
    static CONST WORD Green         = 0x000A;       // 緑
    static CONST WORD Cyan          = 0x000B;       // 水
    static CONST WORD Red           = 0x000C;       // 赤
    static CONST WORD Magenta       = 0x000D;       // 紫
    static CONST WORD Yellow        = 0x000E;       // 黄
    static CONST WORD White         = 0x000F;       // 白
};
 
class CConsole
{
private:
    enum { MaxVK = 256 };
 
private:
    HANDLE m_in;
    HANDLE m_out;
    BOOL m_key[MaxVK];
    COORD m_mouse;
 
public:
    VOID (*OnKeyDown) (WORD vk);
    VOID (*OnKeyUp) (WORD vk);
    VOID (*OnMouseMove) (SHORT x, SHORT y);
    VOID (*OnMouseLeftClick) (SHORT x, SHORT y);
    VOID (*OnMouseLeftDoubleClick) (SHORT x, SHORT y);
    VOID (*OnMouseRightClick) (SHORT x, SHORT y);
    VOID (*OnMouseRightDoubleClick) (SHORT x, SHORT y);
    VOID (*OnFocusChanged) (BOOL fcs);
 
public:
    CConsole (VOID);
    ~CConsole (VOID);
 
public:
    BOOL SetWindowSize (SHORT w, SHORT h);
    BOOL SetCursorVisible (BOOL enb);
    BOOL SetCursorSize (DWORD size);
    BOOL SetCursorPostion (COORD pos);
    BOOL SetCursorPostion (SHORT x, SHORT y);
    BOOL SetFgColor (WORD col);
    BOOL SetBgColor (WORD col);
   
    BOOL GetWindowSize (SMALL_RECT& rect);
    BOOL GetWindowSize (SHORT& x, SHORT& y, SHORT& w, SHORT& h);
    BOOL GetCursorVisible (BOOL& enb);
    BOOL GetCursorSize (DWORD& size);
    BOOL GetCursorPostion (COORD& pos);
    BOOL GetCursorPostion (SHORT& x, SHORT& y);
    BOOL GetFgColor (WORD& col);
    BOOL GetBgColor (WORD& col);
    BOOL GetKeyState (WORD vk);
 
    BOOL ProcessMessage (VOID);
 
private:
    VOID Init (VOID);
    VOID KeyEvent (KEY_EVENT_RECORD rec);
    VOID MouseEvent (MOUSE_EVENT_RECORD rec);
    VOID FocusEvent (FOCUS_EVENT_RECORD rec);
    VOID MouseClickCheck (MOUSE_EVENT_RECORD rec, DWORD mask, VOID (*func) (SHORT x, SHORT y));
    VOID MouseMoveCheck (MOUSE_EVENT_RECORD rec, VOID (*func) (SHORT x, SHORT y));
};


<< Console.cpp >>
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#include "console.h"
 
// コンストラクタ
CConsole::CConsole (VOID)
{
    Init ();
}
 
// デストラクタ
CConsole::~CConsole (VOID)
{
}
 
// メンバ変数の初期化
VOID CConsole::Init (VOID)
{
    // 色々と初期化しておく
    m_in  = GetStdHandle (STD_INPUT_HANDLE);
    m_out = GetStdHandle (STD_OUTPUT_HANDLE);
 
    for (INT i = 0; i < CConsole::MaxVK; ++i)
    {
        m_key[i] = FALSE;
    }
 
    m_mouse.X = -1;
    m_mouse.Y = -1;
 
    OnKeyDown = NULL;
    OnKeyUp = NULL;
    OnMouseMove = NULL;
    OnMouseLeftClick = NULL;
    OnMouseLeftDoubleClick = NULL;
    OnMouseRightClick = NULL;
    OnMouseRightDoubleClick = NULL;
}
 
// Windowサイズの設定
BOOL CConsole::SetWindowSize (SHORT w, SHORT h)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        // Windowsサイズを変更する(ここは失敗の可能性があるので判定の対象外とする
        csbi.srWindow.Left = 0;
        csbi.srWindow.Top = 0;
        csbi.srWindow.Right = w - 1;
        csbi.srWindow.Bottom = h - 1;
        SetConsoleWindowInfo (m_out, TRUE, &csbi.srWindow);
 
        // バッファのサイズを変更し、それにWindowsのサイズを合わせる。
        COORD size = {w, h};
        return  SetConsoleScreenBufferSize (m_out, size) &
                SetConsoleWindowInfo (m_out, TRUE, &csbi.srWindow) &
                GetConsoleScreenBufferInfo (m_out, &csbi);
    }
    return FALSE;
}
 
// カーソル表示の設定
BOOL CConsole::SetCursorVisible (BOOL enb)
{
    CONSOLE_CURSOR_INFO cci;
    if (GetConsoleCursorInfo (m_out, &cci))
    {
        cci.bVisible = enb;
        return  SetConsoleCursorInfo (m_out, &cci) &
                GetConsoleCursorInfo (m_out, &cci);
    }
    return FALSE;
}
 
// カーソルの大きさ設定(1~100)
BOOL CConsole::SetCursorSize (DWORD size)
{
    CONSOLE_CURSOR_INFO cci;
    if (GetConsoleCursorInfo (m_out, &cci))
    {
        cci.dwSize = size;
        return  SetConsoleCursorInfo (m_out, &cci) &
                GetConsoleCursorInfo (m_out, &cci);
    }
    return FALSE;
}
 
// カーソル位置の設定
BOOL CConsole::SetCursorPostion (COORD pos)
{
    return SetCursorPostion (pos.X, pos.Y);
}
 
// カーソル位置の設定
BOOL CConsole::SetCursorPostion (SHORT x, SHORT y)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        csbi.dwCursorPosition.X = x;
        csbi.dwCursorPosition.Y = y;
        return  SetConsoleCursorPosition (m_out, csbi.dwCursorPosition);
                GetConsoleScreenBufferInfo (m_out, &csbi);
    }
    return FALSE;
}
 
// 前景色の設定
BOOL CConsole::SetFgColor (WORD col)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        WORD fg = col & 0x000F;
        WORD bg = csbi.wAttributes & 0x00F0;
        return  SetConsoleTextAttribute (m_out, fg + bg) &
                GetConsoleScreenBufferInfo (m_out, &csbi);
    }
    return FALSE;
}
 
// 背景色の設定
BOOL CConsole::SetBgColor (WORD col)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        WORD bg = (col << 4) & 0x00F0;
        WORD fg = csbi.wAttributes & 0x000F;
        return  SetConsoleTextAttribute (m_out, fg + bg) &
                GetConsoleScreenBufferInfo (m_out, &csbi);
    }
    return FALSE;
}
 
// Windowサイズの取得
BOOL CConsole::GetWindowSize (SMALL_RECT& rect)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        rect = csbi.srWindow;
        return TRUE;
    }
    else
    {
        rect.Left = 0;
        rect.Top = 0;
        rect.Right = 0;
        rect.Bottom = 0;
        return FALSE;
    }
}
 
// Windowサイズの取得
BOOL CConsole::GetWindowSize (SHORT& x, SHORT& y, SHORT& w, SHORT& h)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        x = csbi.srWindow.Left;
        y = csbi.srWindow.Top;
        w = csbi.srWindow.Right + 1;
        h = csbi.srWindow.Bottom + 1;
        return TRUE;
    }
    else
    {
        x = 0;
        y = 0;
        w = 0;
        h = 0;
        return FALSE;
    }
}
 
// カーソル表示状態の取得
BOOL CConsole::GetCursorVisible (BOOL& enb)
{
    CONSOLE_CURSOR_INFO cci;
    if (GetConsoleCursorInfo (m_out, &cci))
    {
        enb = cci.bVisible;
        return TRUE;
    }
    else
    {
        enb = FALSE;
        return FALSE;
    }
}
 
// カーソルサイズの取得
BOOL CConsole::GetCursorSize (DWORD& size)
{
    CONSOLE_CURSOR_INFO cci;
    if (GetConsoleCursorInfo (m_out, &cci))
    {
        size = cci.dwSize;
        return TRUE;
    }
    else
    {
        size = 0;
        return FALSE;
    }
}
 
// カーソル位置の取得
BOOL CConsole::GetCursorPostion (COORD& pos)
{
    return GetCursorPostion (pos.X, pos.Y);
}
 
// カーソル位置の取得
BOOL CConsole::GetCursorPostion (SHORT& x, SHORT& y)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        x = csbi.dwCursorPosition.X;
        y = csbi.dwCursorPosition.Y;
        return TRUE;
    }
    else
    {
        x = 0;
        y = 0;
        return FALSE;
    }
}
 
// 前景色の取得
BOOL CConsole::GetFgColor (WORD& col)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        col = csbi.wAttributes & 0x000F;
        return TRUE;
    }
    else
    {
        col = 0x0000;
        return FALSE;
    }
}
 
// 背景色の取得
BOOL CConsole::GetBgColor (WORD& col)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo (m_out, &csbi))
    {
        col = (csbi.wAttributes & 0x00F0) >> 4;
        return TRUE;
    }
    else
    {
        col = 0x0000;
        return FALSE;
    }
}
 
// キー押下状態の取得
BOOL CConsole::GetKeyState (WORD vk)
{
    return m_key[vk];
}
 
// イベント処理
BOOL CConsole::ProcessMessage (VOID)
{
    // イベントレコード数を取得する
    DWORD cnt = 0;
    if (!GetNumberOfConsoleInputEvents(m_in, &cnt))
    {
        return FALSE;
    }
 
    // イベント処理
    for (DWORD i = 0; i < cnt; ++i)
    {
        // イベントレコードの取得
        INPUT_RECORD rec;
        if (!ReadConsoleInput(m_in, &rec, 1, &cnt))
        {
            return FALSE;
        }
 
        // イベントの処理
        switch (rec.EventType)
        {
        case KEY_EVENT:
            KeyEvent (rec.Event.KeyEvent);
            break;
        case MOUSE_EVENT:
            MouseEvent (rec.Event.MouseEvent);
            break;
        case FOCUS_EVENT:
            FocusEvent (rec.Event.FocusEvent);
            break;
        default:
            break;
        }
    }
    return TRUE;
}
 
// キー関連イベントの処理
VOID CConsole::KeyEvent (KEY_EVENT_RECORD rec)
{
    if (m_key[rec.wVirtualKeyCode] != rec.bKeyDown)
    {
        m_key[rec.wVirtualKeyCode] = rec.bKeyDown;
        if (OnKeyDown != NULL)
        {
            if (m_key[rec.wVirtualKeyCode])
            {
                OnKeyDown (rec.wVirtualKeyCode);
            }
            else
            {
                OnKeyUp (rec.wVirtualKeyCode);
            }
        }
    }
}
 
// マウス関連イベントの処理
VOID CConsole::MouseEvent (MOUSE_EVENT_RECORD rec)
{
    switch (rec.dwEventFlags)
    {
    // クリック
    case 0:
        MouseClickCheck (rec, FROM_LEFT_1ST_BUTTON_PRESSED, OnMouseLeftClick);
        MouseClickCheck (rec, RIGHTMOST_BUTTON_PRESSED, OnMouseRightClick);
        break;
    // 移動
    case MOUSE_MOVED:
        MouseMoveCheck (rec, OnMouseMove);
        break;
    // ダブルクリック
    case DOUBLE_CLICK:
        MouseClickCheck (rec, FROM_LEFT_1ST_BUTTON_PRESSED, OnMouseLeftDoubleClick);
        MouseClickCheck (rec, RIGHTMOST_BUTTON_PRESSED, OnMouseRightDoubleClick);
        break;
    }
}
 
// フォーカス関連イベントの処理
VOID CConsole::FocusEvent (FOCUS_EVENT_RECORD rec)
{
    if (OnFocusChanged != NULL)
    {
        OnFocusChanged (rec.bSetFocus);
    }
}
 
// マウスクリック状態のチェック
VOID CConsole::MouseClickCheck (MOUSE_EVENT_RECORD rec, DWORD mask, VOID (*func) (SHORT x, SHORT y))
{
    if ((rec.dwButtonState & mask) != 0)
    {
        if (func != NULL)
        {
            func (rec.dwMousePosition.X, rec.dwMousePosition.Y);
        }
    }
}
 
// マウス移動のチェック
VOID CConsole::MouseMoveCheck (MOUSE_EVENT_RECORD rec, VOID (*func) (SHORT x, SHORT y))
{
    if (m_mouse.X != rec.dwMousePosition.X ||
        m_mouse.Y != rec.dwMousePosition.Y)
    {
        if (func != NULL)
        {
            m_mouse = rec.dwMousePosition;
            func (m_mouse.X, m_mouse.Y);
        }
    }
}
最後に編集したユーザー バグ [ 2013年10月18日(金) 15:49 ], 累計 1 回