#ifdefと#if #defineの違い

#include <stdio.h>
#define DEBUG
#ifdef DEBUG
    printf("DEBUGモードです。\n");
#endif
#define VERSION 2
#if VERSION >= 3
    printf("最新バージョンです。\n");
#else
    printf("古いバージョンです。\n");
#endif
***************************************
#include <stdio.h>
#define DEBUG
#define VERSION 2
#if defined(DEBUG) && VERSION >= 3
    printf("DEBUGモードかつ最新バージョンです。\n");
#elif defined(DEBUG) || VERSION >= 3
    printf("DEBUGモードまたは最新バージョンです。\n");
#else
    printf("通常モードかつ古いバージョンです。\n");
#endif

C++iniファイル読み書き

#include <iostream>
#include <Windows.h>
int main() {
    // INIファイルのパスとセクション、キーを指定
    LPCWSTR iniFilePath = L"C:\\Users\\sannp\\Desktop\\SAMC1\\INI\\COM.ini";
    LPCWSTR section = L"FTE";
    // キーを指定
    //LPCWSTR key1 = L"section1";
    //LPCWSTR key2 = L"section2";
    //LPCWSTR key3 = L"section3";
    LPCWSTR keys[3] = { L"section1", L"section2",  L"section3" };
    //// 書き込む文字列
    //LPCWSTR writeString = L"Hello, World!";
    //// 書き込む文字列のサイズ(バイト単位)
    //DWORD writeSize = static_cast<DWORD>*1;
    //// INIファイルへの書き込み
    //for (int i = 0; i < 3; ++i) {
    //    BOOL writeResult = WritePrivateProfileString(section, key[i], writeString, iniFilePath);
    //    if (writeResult == FALSE) {
    //        std::cerr << "Failed to write to INI file." << std::endl;
    //        return 1;
    //    }
    //}
    // 読み込み用のバッファ
    //wchar_t buf1[256];
    //wchar_t buf2[256];
    //wchar_t buf3[256];
    wchar_t buf[256];
    for (int i = 0; i < 3; ++i) {
        // INIファイルからデータを取得
        DWORD bytesRead = GetPrivateProfileString(section, keys[i], NULL, buf, sizeof(buf) / sizeof(wchar_t), iniFilePath);
        // 取得したデータを表示
        if (bytesRead > 0) {
            std::wcout << "Data read from " << keys[i] << ": " << buf << std::endl;
        }
    }
    //// INIファイルからデータを取得
    //DWORD bytesRead1 = GetPrivateProfileString(section, key1, NULL, buf1, sizeof(buf1) / sizeof(wchar_t), iniFilePath);
    //DWORD bytesRead2 = GetPrivateProfileString(section, key2, NULL, buf2, sizeof(buf2) / sizeof(wchar_t), iniFilePath);
    //DWORD bytesRead3 = GetPrivateProfileString(section, key3, NULL, buf3, sizeof(buf3) / sizeof(wchar_t), iniFilePath);
    //// 取得したデータを表示
    //if (bytesRead1 > 0) {
    //    std::wcout << "Data read from " << key1 << ": " << buf1 << std::endl;
    //}
    //if (bytesRead2 > 0) {
    //    std::wcout << "Data read from " << key2 << ": " << buf2 << std::endl;
    //}
    //if (bytesRead3 > 0) {
    //    std::wcout << "Data read from " << key3 << ": " << buf3 << std::endl;
    //}
    return 0;
}

*1:wcslen(writeString) + 1) * sizeof(wchar_t

C++ visa通信

#include <visa.h> // Keysight IOライブラリ・スイートのヘッダーファイル

#include <iostream>
#include <string>

int main() {
    ViSession defaultRM, instr;
    ViStatus status;
    ViChar buffer[256];

    // VISAデバイスの初期化
    status = viOpenDefaultRM(&defaultRM);
    if (status < VI_SUCCESS) {
        std::cerr << "Error opening VISA Resource Manager" << std::endl;
        return 1;
    }

    // VISAデバイスのオープン
    status = viOpen(defaultRM, "USB0::0x1234::0x5678::INSTR", VI_NULL, VI_NULL, &instr);
    if (status < VI_SUCCESS) {
        std::cerr << "Error opening device" << std::endl;
        return 1;
    }

    // VISAデバイスにクエリを送信して応答を取得
    status = viQueryf(instr, "*IDN?", "%t", buffer);
    if (status < VI_SUCCESS) {
        std::cerr << "Error querying device" << std::endl;
        return 1;
    }

    // 応答を表示
    std::cout << "Instrument ID: " << buffer << std::endl;

    // VISAデバイスのクローズ
    viClose(instr);
    viClose(defaultRM);

    return 0;
}

C++関連その3

コンソールサイズ設定

consol_size_set(800, 600);

int consol_size_set(short int x, short int y) {
// コンソールウィンドウのハンドルを取得
HWND console = GetConsoleWindow();
if (console == NULL) {
return 1; // エラー処理
}
 
// ウィンドウのサイズを設定
RECT rect;
GetWindowRect(console, &rect);
MoveWindow(console, rect.left, rect.top, x, y, TRUE);
 
// コンソールウィンドウをアクティブにする
SetForegroundWindow(console);
 
return 0;
}
------------------------------------------------------

C++標準ライブラリには、initgraph() という関数は含まれていません。initgraph() 関数は、古いBorland Graphics Interface (BGI) ライブラリで提供されていました。この関数は、グラフィカルな画面の初期化や描画環境の設定を行うために使用されました。

BGI ライブラリは、Turbo C++Borland C++ 等の古いC++コンパイラで使用されていましたが、現代のC++開発においては非推奨とされています。代わりに、より現代的なグラフィックスライブラリやフレームワークを使用することが一般的です。例えば、SFMLやOpenGLなどがあります。

------------------------------------------------------

textmode(C8025) のような形式の関数呼び出しは、古いMS-DOSBorland C++の環境で使用されていたものです。この関数は、グラフィックスモードに切り替えるために使用されました。C8025 は、特定のグラフィックスモードを指定していますが、異なる環境では異なる値になります。

具体的には、C8025 がどのようなグラフィックスモードを表しているかは、使用している環境やコンパイラによって異なります。そのため、このコードは環境依存であり、一般的なC++のコードではありません。

************************************************************

free() 関数は、動的に割り当てられたメモリ領域を解放するための関数です。PortInfo[PortNo].RecBuffer がポインタであり、その指すメモリ領域を解放します。

以下は、free() 関数の使用例です。

#include <cstdlib>

// メモリの割り当て
PortInfo[PortNo].RecBuffer = (char*)malloc(100); // 例として100バイトを割り当てたとします

// 割り当てたメモリ領域の使用

// メモリの解放
free(PortInfo[PortNo].RecBuffer);

この例では、malloc() 関数を使用して100バイトのメモリを動的に割り当てています。その後、そのメモリを使用した後に free() 関数を使用してメモリを解放しています。メモリを解放することで、その領域を他の目的に再利用できるようになります。

************************************************************

segread() は、古いMS-DOS環境で使用されていた関数の一つです。この関数は、セグメントレジスタの値を取得するために使用されました。

具体的には、segread() 関数は、セグメントレジスタの値を取得し、それを構造体に格納します。この構造体は SREGS と呼ばれ、以下のような定義があります。

struct SREGS {
    unsigned int es;
    unsigned int cs;
    unsigned int ss;
    unsigned int ds;
};

segread() 関数は、この構造体を引数として受け取り、セグメントレジスタ escsssds のそれぞれの値を設定します。

しかし、これらのセグメントレジスタの値を直接取得する必要がない場合は、現代のC++開発では通常使用されません。代わりに、OS固有のAPIやライブラリを使用して、必要な情報を取得することが一般的です。

以下は、Windows環境での例です。Windows APIGetThreadSelectorEntry() 関数を使用して、指定されたセグメントレジスタの情報を取得することができます。

#include <windows.h>

void getSegmentRegisters() {
    // セグメントレジスタの値を格納するための変数
    LDT_ENTRY entry;

    // DSレジスタの情報を取得
    GetThreadSelectorEntry(GetCurrentThread(), static_cast<DWORD>(__readfsbase()), &entry);

    // セグメントレジスタの情報を使用する
    unsigned int dsValue = entry.BaseLow | (entry.HighWord.Bytes.BaseMid << 16) | (entry.HighWord.Bytes.BaseHi << 24);
    // dsValue に DSレジスタの値が格納される
}

この例では、GetThreadSelectorEntry() 関数を使用して、現在のスレッドのセグメントレジスタの情報を取得しています。この方法で、セグメントレジスタの値を取得することができます。ただし、各セグメントレジスタに関する情報を取得するためには、適切な引数を指定する必要があります(例えば、GetCurrentThread()__readfsbase() を使用して、DSレジスタの情報を取得しています)。

************************************************************

registerbgidriver() 関数は、BGI (Borland Graphics Interface) ライブラリで使用される関数であり、特定のデバイスドライバを登録するために使用されました。しかし、BGI ライブラリは古いものであり、現代のC++開発にはあまり使用されません。

#include <graphics.h>

int registerbgidriver(void (*driver)(void));

registerbgidriver を使用すると、ユーザーはドライバー ファイルをロードし、ドライバーを「登録」できます。メモリの場所が registerbgidriver に渡されると、initgraph は登録されたドライバーを使用します。ユーザー登録ドライバーは、ディスクからヒープにロードすることも、.OBJ ファイルに変換して (BGIOBJ.EXE を使用)、.EXE にリンクすることもできます。

registerbgidriver を呼び出すと、driver が指すドライバーがリンク時に組み込まれたことがグラフィック システムに通知されます。このルーチンは、指定されたドライバーのリンクされたコードをチェックします。コードが有効な場合は、そのコードを内部テーブルに登録します。

registerbgidriver の呼び出しでリンクされたドライバーの名前を使用すると、そのパブリック名を使用してオブジェクト ファイルにリンクするようにコンパイラー (およびリンカー) に指示することもできます。

************************************************************

graphics.h は、古いBorland Graphics Interface (BGI) ライブラリで使用されるヘッダーファイルです。BGI ライブラリは、グラフィカルなアプリケーションを開発するためのツールとして提供されましたが、今日では非推奨となっています。

以下は、一般的に graphics.h ヘッダーファイルで提供される可能性のある機能や定義の例です(これはすべての実装で共通して提供されるわけではありません)。

  1. グラフィックス関連の定数:

    • DETECT: グラフィックスドライバを自動検出するための定数
    • VGA: VGAグラフィックスドライバを指定するための定数
    • EGA: EGAグラフィックスドライバを指定するための定数
    • その他、色や線種などの定数が含まれる場合があります
  2. グラフィックス関連の関数:

    • initgraph(): グラフィックスモードを初期化する関数
    • closegraph(): グラフィックスモードを終了する関数
    • getch(): キー入力を待ち受ける関数
    • putpixel(): ピクセルを描画する関数
    • line(): 直線を描画する関数
    • circle(): 円を描画する関数
    • rectangle(): 矩形を描画する関数
    • その他、描画や入力関連の機能が含まれる場合があります
  3. グラフィックス関連のデータ型:

    • struct xycoord: x座標とy座標を持つデータ型
    • struct linesettingstype: 描画する線のスタイルを保持するデータ型
    • その他、色やパターンなどを表すデータ型が含まれる場合があります

これらの機能や定義は、C++の標準ライブラリではなく、Borland Turbo C++などの古いC++コンパイラで提供されるものです。現代のC++開発では、よりモダンなグラフィックスライブラリやフレームワークを使用することが推奨されています。

Visual C++ (VC++) では、古いBorland Graphics Interface (BGI) ライブラリの代わりに、よりモダンで柔軟なグラフィックスライブラリやフレームワークを使用することが推奨されます。以下は、VC++で使える代替としてよく使用されるもののいくつかです。

  1. DirectX: DirectX は、Microsoftが提供するグラフィックスとマルチメディアのAPIです。DirectXを使用することで、ゲームやマルチメディアアプリケーションを開発することができます。特に、DirectX 9以降のバージョンでは、Direct2DやDirect3Dを使用して2Dおよび3Dの描画を行うことができます。

  2. OpenGL: OpenGLは、クロスプラットフォームの3DグラフィックスAPIであり、Windowsでも利用可能です。OpenGLを使用することで、ハードウェアアクセラレーションを利用した高性能な3D描画を行うことができます。さらに、OpenGLは2D描画にも使用することができます。

  3. SFML (Simple and Fast Multimedia Library): SFMLは、C++でゲームやマルチメディアアプリケーションを開発するためのモダンなライブラリです。SFMLは、ウィンドウの管理、グラフィックス描画、音声再生、入力処理など、さまざまな機能を提供します。また、クロスプラットフォームであり、WindowsLinuxmacOSなどで使用することができます。

  4. WinAPI: Windows APIを使用して、ウィンドウやデバイスコンテキストを直接操作することもできます。これにより、Windowsアプリケーションの開発やカスタマイズが可能になりますが、OpenGLやSFMLのようなライブラリを使用することで、より高レベルな抽象化を得ることができます。

  5. ****************************
  6.  

グラフィック関係

putimage() 関数は、古いBGIBorland Graphics Interface)などのグラフィックスライブラリで使用されており、イメージを画面上の指定された位置に描画します。標準C++には含まれていないため、直接的な代替関数はありません。

しかし、グラフィックス描画のためには、標準C++には含まれていないが広く使用されているライブラリがいくつかあります。その中には、SDL(Simple DirectMedia Layer)、SFML(Simple and Fast Multimedia Library)、OpenCV(Open Source Computer Vision Library)などがあります。これらのライブラリは、さまざまなプラットフォームでグラフィックスやイメージの描画を行うための豊富な機能を提供しています。

以下は、SDLライブラリを使用してイメージを描画する簡単な例です。

#include <iostream>
#include <SDL.h>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main() {
    // SDLの初期化
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    // ウィンドウの作成
    SDL_Window* window = SDL_CreateWindow("SDL Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    // ウィンドウにレンダラーを作成
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (renderer == nullptr) {
        std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    // 画像の読み込み
    SDL_Surface* imageSurface = SDL_LoadBMP("image.bmp");
    if (imageSurface == nullptr) {
        std::cerr << "Unable to load image! SDL_Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    // 画像をテクスチャに変換
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, imageSurface);
    if (texture == nullptr) {
        std::cerr << "Unable to create texture! SDL_Error: " << SDL_GetError() << std::endl;
        return 1;
    }
    SDL_FreeSurface(imageSurface);

    // テクスチャを描画
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);

    // 3秒待つ
    SDL_Delay(3000);

    // ウィンドウとレンダラーの解放
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    // SDLの終了
    SDL_Quit();

    return 0;
}

このプログラムでは、SDLライブラリを使用して画像をウィンドウに描画しています。SDL_LoadBMP() 関数を使用して画像を読み込み、SDL_CreateTextureFromSurface() 関数を使用してテクスチャを作成します。そして、SDL_RenderCopy() 関数を使用してテクスチャを描画します。このプログラムは、SDLライブラリの初期化、ウィンドウの作成、イメージの読み込みなど、基本的なステップを示しています。

-------------------------------

line() 関数は、グラフィックス描画ライブラリで直線を描画するために使用されます。古いBGIBorland Graphics Interface)などのグラフィックスライブラリでは一般的でしたが、標準C++には含まれていません。

代替関数は、使用しているグラフィックスライブラリに依存します。例えば、Windows環境でGDI(Graphics Device Interface)を使用してグラフィックスを描画している場合、MoveToEx() 関数と LineTo() 関数を使用して直線を描画することができます。

以下に、Windows環境での例を示します。

#include <Windows.h>

// グラフィックスデバイスコンテキストに直線を描画する関数
void DrawLine(HDC hdc, int x1, int y1, int x2, int y2) {
    MoveToEx(hdc, x1, y1, NULL); // 始点を設定
    LineTo(hdc, x2, y2); // 終点まで直線を描画
}

int main() {
    HWND hwnd = GetConsoleWindow(); // ウィンドウハンドルを取得(コンソールウィンドウの場合)
    HDC hdc = GetDC(hwnd); // ウィンドウのデバイスコンテキストを取得

    // 直線を描画
    DrawLine(hdc, 100, 100, 200, 200);

    ReleaseDC(hwnd, hdc); // デバイスコンテキストを解放

    return 0;
}

この例では、MoveToEx() 関数で始点を設定し、LineTo() 関数で終点まで直線を描画しています。GetDC() 関数を使用してウィンドウのデバイスコンテキストを取得し、ReleaseDC() 関数を使用してデバイスコンテキストを解放しています。

グラフィックスライブラリやフレームワークによっては、直線を描画するための独自の関数が提供される場合があります。その場合は、そのライブラリやフレームワークのドキュメントを参照してください。

--------------------

setfillstyle() 関数は、古いBGIBorland Graphics Interface)などのグラフィックスライブラリで使用されており、図形の塗りつぶしスタイルを設定します。標準C++には含まれていないため、直接的な代替関数はありません。

しかし、代替手段として、異なるグラフィックスライブラリを使用することができます。例えば、SDL(Simple DirectMedia Layer)、SFML(Simple and Fast Multimedia Library)、OpenGLなどのライブラリを使用して、図形の描画や塗りつぶしを行うことができます。

以下は、SFMLライブラリを使用して図形の塗りつぶしを行う例です。

#include <SFML/Graphics.hpp>

int main() {
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Example");

    // 四角形の塗りつぶしスタイルを設定
    sf::RectangleShape rectangle(sf::Vector2f(200, 100));
    rectangle.setFillColor(sf::Color::Red);
    rectangle.setPosition(100, 100);

    // ウィンドウが開いている間、描画を続ける
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }

        // ウィンドウをクリアして描画
        window.clear();
        window.draw(rectangle);
        window.display();
    }

    return 0;
}

この例では、SFMLライブラリを使用してウィンドウを作成し、sf::RectangleShape クラスを使用して四角形を作成しています。setFillColor() 関数を使用して四角形の塗りつぶし色を設定し、draw() 関数を使用してウィンドウに四角形を描画しています。SFMLライブラリの利用方法は、簡単で柔軟であり、図形の描画や塗りつぶしを行うために使われます。

--------------------

データファイルをプリンターに出力するプログラム

#include <iostream>
#include <Windows.h>
void PrintFile(const std::string& filename) {
    // デフォルトのプリンターを取得
    DWORD bufsize = 256;
    char printerName[256];
    GetDefaultPrinter(printerName, &bufsize);
    // プリンターデバイスコンテキストを取得
    HDC hdc = CreateDC("WINSPOOL", printerName, NULL, NULL);
    // ファイルを開く
    HANDLE hFile = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "Failed to open file: " << filename << std::endl;
        return;
    }
    // ファイルの内容を読み取ってプリンターに送信
    DWORD bytesRead;
    BYTE buffer[4096];
    while (ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {
        DWORD bytesWritten;
        WritePrinter(hdc, buffer, bytesRead, &bytesWritten);
    }
    // リソースを解放
    ClosePrinter(hdc);
    CloseHandle(hFile);
}
int main() {
    std::string filename = "example.txt"; // 出力するファイル名を指定
    PrintFile(filename); // 指定したファイルをプリンターに出力
    return 0;
}

C++キー入力関連

    std::cout << "キーを入力してください: ";

    switch (_getch())
    {
    case 0xe0:
        switch (_getch())
        {
        case 0x48: printf("↑"); break;
        case 0x50: printf("↓"); break;
        case 0x4b: printf("←"); break;
        case 0x4d: printf("→"); break;
        }
        break;
    case 0x0d: printf("Enter");break;
    case 0x20: printf("Space");break;
    }

    return 0;

キー一覧:

kts.sakaiweb.com

-----------------------------------------