提示コードのReadConsoleInput()関数ですがGetLastError();関数により[998]が発生しましたそのエラーの解決方法がわかりません。
コンストラクタでハンドルを受け取りそれをキー入力の時に使っています。
エラー[998] : メモリ ロケーションへのアクセスが無効です。
公式リファレンス: https://docs.microsoft.com/ja-jp/windows/console/readconsoleinput
cpp
1#include "stdio.h" 2#include "stdlib.h" 3#include <Windows.h> 4#include "stdio.h" 5#include "stdlib.h" 6 7 8#include "DrawCharactor.hpp" 9 10 11#include "KeyInput.hpp" 12 13// ウインドウサイズ 14#define MAX_WIDTH ((int)100) 15#define MAX_HEIGHT ((int)40) 16 17FILE* fp = NULL; 18 19 20int main() 21{ 22 fopen_s(&fp,"Mian_Log.txt","w"); 23 DrawCharactor* dc = new DrawCharactor(); 24 KeyInput* key = new KeyInput(dc->getHandle()); 25 26 27 28 int y = 0; 29 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 30 while (true) 31 { 32 if (key->getKeyDown(KeyCode::UP_KEY) == true) 33 { 34 y--; 35 fprintf(fp, "UP\n"); 36 37 } 38 else if (key->getKeyDown(KeyCode::DOWN_KEY) == true) 39 { 40 fprintf(fp,"Down\n"); 41 y++; 42 } 43 // fprintf(fp, "Down\n"); 44 45 46 for (int i = 0; i < 5; i++) 47 { 48 if (y == i) 49 { 50 dc->setDraw("-> "); 51 dc->setDraw_Line("AAAA"); 52 53 } 54 else 55 { 56 dc->setDraw_Line("AAAA"); 57 } 58 } 59 60 61 62 63 64 65 66 67 /// dc->setDraw_Line("Menu "); 68 // dc->setDraw_Line("test"); 69 70 71 72 73 74 dc->GenerateOutput(); 75 } 76 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 77 78 delete dc; 79 delete key; 80 81 82 fclose(fp); 83 84 85 86 return 0; 87}
cpp
1#include "KeyInput.hpp" 2 3KeyInput::KeyInput(HANDLE h) 4{ 5 handle = h; 6 7 Length = sizeof(INPUT_RECORD); 8 lpNumber = 0; 9 10 fopen_s(&fp,"KeyInput.txt","w"); 11 12 13} 14 15// キーが押された瞬間だけ 16bool KeyInput::getKeyDown(KeyCode key) { 17 18////////////////////////////////////////////////////////////////////////// 19 if (ReadConsoleInput(handle, Buffer, Length, &lpNumber) != 0) 20 { 21 fprintf(fp, "あああ\n"); 22///////////////////////////////////////////////////////////////////////// 23 if (Buffer->Event.KeyEvent.bKeyDown == true) { 24 if (Buffer->Event.KeyEvent.wVirtualKeyCode == (int)key && b == false) 25 { 26 b = true; 27 return true; 28 } 29 } 30 else 31 { 32 b = false; 33 return false; 34 } 35 36 } 37 else { 38 fprintf(fp, "ReadConsoleInput()が無効です。 %d\n",GetLastError()); 39 40 return false; 41 } 42 43 return false; 44} 45 46 47 48bool KeyInput::getKeyHoldDown() 49{ 50 return false; 51} 52 53 54KeyInput::~KeyInput() 55{ 56 fclose(fp); 57} 58
hpp
1#ifndef ___KEYINPUT_HPP_ 2#define ___KEYINPUT_HPP_ 3#include <iostream> 4#include "stdlib.h" 5#include "stdio.h" 6 7#include <Windows.h> 8 9 10 11class KeyInput 12{ 13public: 14 15 16 KeyInput(HANDLE h); //コンストラクタ 17 ~KeyInput(); //デストラクタ 18 19 bool getKeyDown(enum class KeyCode key); //キーが押された時 (瞬間だけ) 20 bool getKeyHoldDown(); //キーが押されてる間 21 22 23 24private: 25 26 bool b = false; 27 HANDLE handle; 28 INPUT_RECORD *Buffer = nullptr; 29 DWORD Length; 30 DWORD lpNumber; 31 32 FILE* fp = NULL; //デバッグログ 33 34}; 35 36 37// キーコード 38enum class KeyCode 39{ 40 41 A_KEY = 0x41, 42 B_KEY = 0x43, 43 C_KEY = 0x44, 44 D_KEY = 0x45, 45 E_KEY = 0x46, 46 F_KEY = 0x47, 47 G_KEY = 0x48, 48 H_KEY = 0x49, 49 I_KEY = 0x4A, 50 J_KEY = 0x4B, 51 K_KEY = 0x4C, 52 L_KEY = 0x4D, 53 M_KEY = 0x4E, 54 N_KEY = 0x4F, 55 O_KEY = 0x50, 56 P_KEY = 0x51, 57 Q_KEY = 0x52, 58 R_KEY = 0x53, 59 S_KEY = 0x54, 60 T_KEY = 0x55, 61 U_KEY = 0x56, 62 V_KEY = 0x57, 63 W_KEY = 0x58, 64 X_KEY = 0x59, 65 Y_KEY = 0x5A, 66 Z_KEY = 0x5A, 67 68 LEFT_KEY = 0x25, //左矢印キー 69 UP_KEY = 0x26, //上矢印キー 70 RIGHT_KEY = 0x27, //右矢印キー 71 DOWN_KEY = 0x28, //下矢印キー 72 SPACE_KEY = 0x20, //スペースキー 73 74 75}; 76#endif
cpp
1#include "DrawCharactor.hpp" 2 3// コンストラクタ 4DrawCharactor::DrawCharactor() 5{ 6 fopen_s(&fp,"Log.txt","w"); //ファイル 7 8 9 //描画開始座標 10 mDraw_start.X = 0; 11 mDraw_start.Y = 0; 12 13 //描画範囲 14 mDraw_size.X = MAX_WIDTH; 15 mDraw_size.Y = MAX_HEIGHT; 16 17 //ウインドウサイズ 18 mRect.Left = (SHORT)0; 19 mRect.Top = (SHORT)0; 20 mRect.Right = (SHORT)MAX_WIDTH; 21 mRect.Bottom = (SHORT)MAX_HEIGHT; 22 23 // バッファーを作成 24 mHandle = CreateConsoleScreenBuffer(GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 25 26 SetConsoleActiveScreenBuffer(mHandle); //有効にする 27 28 if (mHandle == INVALID_HANDLE_VALUE) 29 { 30 fprintf(fp, "Invalid: INVALID_HANDLE_VALUE \n"); 31 } 32 33 // 画面バッファサイス変更 34 if (SetConsoleScreenBufferSize(mHandle, mDraw_size) == 0) 35 { 36 fprintf(fp,"Invalid: SetConsoleScreenBufferSize(); \n"); 37 } 38 39 // 画面サイズ変更 40 if (SetConsoleWindowInfo(mHandle, TRUE, &mRect) != 0) 41 { 42 fprintf(fp, "Invalid: SetConsoleWindowInfo(); \n"); 43 } 44 45} 46 47// バッファーに文字を書き込む 48void DrawCharactor::setDraw(const char* format, ...) 49{ 50 51 va_list ap; 52 char str[MAX_WIDTH]; 53 va_start(ap, format); 54 vsprintf_s(str, sizeof(str), format, ap); 55 va_end(ap); 56 57 wchar_t wc[MAX_WIDTH]; 58 size_t size = sizeof(wc); 59 60 size_t count = sizeof(wc) / sizeof(wchar_t); 61 mbstowcs_s(&size, wc, count, str, count - 1); //マルチ文字をワイド文字に変換 62 63 // ----------------------------------------------------------------------------------------------- 64 int i = 0; 65 for (; mNowBuffer_width[mNowBuffer_height] <= MAX_WIDTH; mNowBuffer_width[mNowBuffer_height]++) { 66 67 if (wc[i] != L'\0') { 68 69 if (mNowBuffer_width[mNowBuffer_height] <= MAX_WIDTH) { 70 mScreenBuffer[mNowBuffer_height][mNowBuffer_width[mNowBuffer_height]].Char.UnicodeChar = wc[i]; 71 mScreenBuffer[mNowBuffer_height][mNowBuffer_width[mNowBuffer_height]].Attributes = FOREGROUND_GREEN; 72 // mNowBuffer_width[mNowBuffer_height]++; 73 74 } 75 else 76 { 77 fprintf(fp,"setDraw() 一行の文字数を超えています。\n"); 78 } 79 i++; 80 } 81 else { 82 break; 83 } 84 } 85 86 // ----------------------------------------------------------------------------------------------- 87 //fprintf(fp, "ああああ\n"); 88} 89 90 91 92 93// バッファーに文字を書き込む 94void DrawCharactor::setDraw_Line(const char* format, ...) 95{ 96 97 va_list ap; 98 char str[MAX_WIDTH]; 99 va_start(ap, format); 100 vsprintf_s(str, sizeof(str), format, ap); 101 va_end(ap); 102 103 wchar_t wc[MAX_WIDTH]; 104 size_t size = sizeof(wc); 105 106 size_t count = sizeof(wc) / sizeof(wchar_t); 107 mbstowcs_s(&size, wc, count, str, count - 1); //マルチ文字をワイド文字に変換 108 109 // ----------------------------------------------------------------------------------------------- 110 int i = 0; 111 for (; mNowBuffer_width[mNowBuffer_height] <= MAX_WIDTH; mNowBuffer_width[mNowBuffer_height]++) { 112 113 if (wc[i] != L'\0') { 114 115 if (mNowBuffer_width[mNowBuffer_height] <= MAX_WIDTH) { 116 mScreenBuffer[mNowBuffer_height][mNowBuffer_width[mNowBuffer_height]].Char.UnicodeChar = wc[i]; 117 mScreenBuffer[mNowBuffer_height][mNowBuffer_width[mNowBuffer_height]].Attributes = FOREGROUND_GREEN; 118 //mNowBuffer_width[mNowBuffer_height]++; 119 120 } 121 else 122 { 123 fprintf(fp, "setDraw_Line() 一行の文字数を超えています。\n"); 124 } 125 i++; 126 } 127 else { 128 break; 129 } 130 } 131 132 mNowBuffer_height++; 133 134 135 // ----------------------------------------------------------------------------------------------- 136 //fprintf(fp, "ああああ\n"); 137} 138 139// 描画 140void DrawCharactor::GenerateOutput() 141{ 142 WriteConsoleOutput(mHandle,mScreenBuffer[0], mDraw_size, mDraw_start, &mRect); //現在のカーソル位置から始まる文字列をコンソール画面バッファーに書き込み 143 mNowBuffer_height = 0; 144 145 for (int i = 0; i < MAX_HEIGHT; i++) 146 { 147 mNowBuffer_width[i] = 0; 148 } 149 150} 151 152// ハンドルを返す 153HANDLE DrawCharactor::getHandle() 154{ 155 return mHandle; 156} 157 158 159// デストラクタ 160DrawCharactor::~DrawCharactor() 161{ 162 // スクリーンバッファを解放 163 CloseHandle(mHandle); 164 mHandle = NULL; 165 166 fclose(fp); 167 168}
mainがないのでビルドして動作確認ができません。
コンストラクタでどんな値を渡したのかも不明ですし、動くコードをはっていただけますか。
mainのソースコードを添付しました。
DrawCharactorって何者ですか…
dc->getHandle()で何が返っているのか不明ですが。
DrawCharactor* dc = new DrawCharactor();
KeyInput* key = new KeyInput(dc->getHandle());
文字数の関係で定義コードは載せられましたが宣言のヘッダーファイルを載せられませんでした。
コードを全部貼るのではなく、コンパイルが通り再現できる最小限のコードで良いのですが…
回答2件
あなたの回答
tips
プレビュー