C言語関係掲示板

過去ログ

No.249.Ctrl+[*]について(ショートカットキー)


No.1504

Ctrl+[*]について
投稿者---ジャスミン茶(2002/05/15 08:59:06)


はじめまして、こんにちは。
一週間ほど前からC言語の勉強をはじめましたジャスミン茶と申します。
質問があって投稿させていただきました。

Cの勉強として簡単なメモ帳(テキストエディタ)を作ろうとしているのですが、
切り取りや貼り付けなどの機能を、ウインドウズのメモ帳のようにCtrl+[*]で実現したいと思っています。
今考えているのは、入力専用の関数を作り、main関数からforループ内で呼び出して使うという事なんです。
getch関数を使って全てのキー入力に対して機能を割り当てたい(入力をアスキーコードに変換して逐一switch文で制御)と思っているのですが、
英数記号やエンター、スペースはいいとして、Ctrl+[*]などはアスキーコードとしては扱えないのでしょうか?
仮にそうだとするとそれらはどのように制御すればいいのでしょうか?

Cを使ったテキストエディタというのがどういう仕組みなのか分かっていないため、
おかしな質問になっているのかもしれませぬ。
(そもそもCでテキストエディタは作らないのでしょうか?)

ちなみに私の環境は、
Windows2000proSP2, Microsoft Visual Studio .Net Academic(よく分からずに買ってしまいました。)
でございまする。

No.1508

Re:Ctrl+[*]について
投稿者---B.Smith(2002/05/15 23:30:27)


こんばんは。

PC(Windows)では16bitコンパイラと32bitコンパイラで方法が変わってきます。
私はMicrosoft Visual Studio .Netを持っていないので良くわかりませんが、恐らく32bitコンパイラだと思います。一応、16bit版での方法も簡単にご紹介しておきますが、32bit版の方で解決出来るはずです。

Windows 32bitコンパイラの場合
Win32 APIに関数GetKeyStateというのがあります。これを使用することでキーの状態を確認することが出来ます。
関数の詳細はヘルプを参照してください。
以下のソースはVisual C++ 6.0で動作確認しました。
テスト1.
#include <windows.h>
#include <conio.h>
#include <stdio.h>

void main(void )
{
    while(!kbhit()){
        printf("Ctrl:%d  Shift:%d  Alt:%d\r",
            (GetKeyState(VK_CONTROL) & 0x80000000)? 1 : 0,
            (GetKeyState(VK_SHIFT) & 0x80000000)? 1 : 0,
            (GetKeyState(VK_MENU) & 0x80000000)? 1 : 0);
    }
    getch();
}

・GetKeyStateの引数に、検査したいキーを設定します。CtrlキーはVK_CONTROL、ShiftキーはVK_SHIFT、AltキーはVK_MENUです。
関数の戻り値の最上位ビットが1ならばキーが押されている、0ならばキーが押されていない、という感じになっています。

・この関数を使用する場合はWindows.hをインクルードしてください。また、DOSコンソール(MS-DOSモード)でコンパイルする場合はUSER32.LIBをリンクしてください。

16bitコンパイラの場合
16bitコンパイラではWin32 APIを使用することが出来ませんので、キーボードBIOSを使う事になります(逆に32bitコンパイラでは、この方法は使えません)。
以下のソースはLSI-C試食版で動作確認しました。
テスト2.
#include <dos.h>
#include <conio.h>
#include <stdio.h>

int     CheckKeyState(void );

void main(void )
{
    while(!kbhit()){
        printf("%x\r",CheckKeyState());
    }

    getch();
}

/* 戻り値                                       */
/* 下位バイト               上位バイト          */
/* bit7 ... 挿入モード      bit7 ... SysRq      */
/* bit6 ... CapsLock        bit6 ... CapsLock   */
/* bit5 ... NumLock         bit5 ... NumLock    */
/* bit4 ... ScrollLock      bit4 ... ScrollLock */
/* bit3 ... Alt             bit3 ... 右Alt      */
/* bit2 ... Ctrl            bit2 ... 右Ctrl     */
/* bit1 ... 左Shift         bit1 ... 左Alt      */
/* bit0 ... 右Shift         bit0 ... 左Ctrl     */

/* 上位バイトはキーボード拡張機能が有効な場合のみ   */

int     CheckKeyState(void )
{
    union REGS          parm;

    /* BIOSワークエリア内からキーボードの種類を調べる   */
    /* 40:96hのbit4が1の時、拡張キーボード              */
    parm.h.ah = (*(unsigned char far *)0x00400096L) & 0x10 | 2;

    /* AHが02hの場合、通常のキーボードステータス        */
    /* AHが12hの場合、拡張キーボードステータス          */

    int86(0x16,&parm,&parm);
}



No.1509

Re:Ctrl+[*]について
投稿者---ジャスミン茶(2002/05/16 04:11:15)


B.Smithさん、はじめまして。
返信ありがとうございます。

なるほど、ウインドウズの機能を使うわけですか。
調べてみたところ他にも、GetAsyncKeyState, GetKeyboardStateなどいくつかありました。
これらを使えばかなり細かいところまでプログラミング出来そうですね。
なんだか面白くなってきました。

ただこれらを使ってしまうと、純粋なCアプリではなくなってしまうような気がするのですが、
そういうものなのでしょうか?
ここまで来ると「せっかくだから入力用の別窓を作って」とか、無謀な事を考えてしまいますが、
やはりC, C++, VC++と順にマスターしていくのが一番なんでしょうね。
いまの私には無理そうですし、先は長そうです。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.06.22
Copyright(c) 2000-2002 TOMOJI All Rights Reserved