SSブログ

[C++]HTMLオブジェクトをクリップボードに転送する [プログラミング]

Visual Basicで実装した機能のC++版
基本的にはこのコードを9割型流用しているが、一部無駄が多かったり変数名がわかりにくかったりがあったので
適宜リファクタリングして使いやすいように修正

手順
C++のコンパイル環境がある場合は③から

①MinGWのインストーラーのダウンロード
http://www.mingw.org/よりDownloadsからセットアップファイルをダウンロード
直リンクは以下
https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/

②MinGWのインストール
mingw-get-setup.exeを実行してInstall
01.png

特に変更せずContinue
02.png

必要なファイルがダウンロードされたらContinue
03.png

以下の行を右クリックしてMark for Installationを選択
mingw32-base-bin
mingw32-gcc-ada-bin
mingw32-gcc-fortran-bin
mingw32-gcc-g++-bin
04.png

以下のようになっていればOK
05.png

メニューのInstallation>Apply Changesを選択
06.png

Applyを選択
07.png

インストールが終わったらCloseを押し、MinGWを終了する
08.png

スタートボタンを右クリック>ファイル名を指定して実行
sysdm.cpl

と入力して実行
09.png

詳細設定>環境変数を選択し、システム環境変数>Pathの行を選択して編集
10.png

新規を選択し、以下のパスを指定する
C:\MinGW\bin
11.png

コマンドプロンプトを起動し、
g++ -v
と入力してバージョン情報が出たらインストール完了
12.png


③実行ファイルの作成
以下のコードを任意のファイル名.cppに保存

#include <stdio.h>
#include <shlwapi.h>
#include <math.h>
#include <iostream>

using namespace std;

static int toClip(int, char **);
static bool convertCharset(int, int, const char *, char **);
static bool toWChar(int, const char *, wchar_t **);
static char *padLeft(long long, int);

enum TOCLIP_RESULT {
	SUCCESS_TOCLIP = 0,
	INVALID_ARG_NUM,
	FAILED_TOWCHAR,
	FAILED_CONVERTCHARSET,
	FAILED_OPENCLIPBOARD
};

#define VALID_TOCLIP_ARG_NUM 4

#define PAD_NUM 10
#define HEAD_START_HTML "Version:1.0\r\nStartHTML:"
#define HEAD_END_HTML "\r\nEndHTML:"
#define HEAD_START_FRAGMENT "\r\nStartFragment:"
#define HEAD_END_FRAGMENT "\r\nEndFragment:"
#define HEAD_LAST "\r\n"
#define START_FRAGMENT "<!--StartFragment-->"
#define END_FRAGMENT "<!--EndFragment-->"
#define HTML_HEAD "<html>"
#define HTML_TAIL "</html>"

int main(int argc, char *argv[])
{
	
	setlocale(LC_ALL, "Japanese_Japan.932");
	
	int toClipResult = toClip(argc, argv);
	switch(toClipResult) {
		case SUCCESS_TOCLIP:
			cout << "Success toClip." << endl;
			break;
		case INVALID_ARG_NUM:
			cout << "Invalid argment num." << endl;
			break;
		case FAILED_TOWCHAR:
			cout << "Failed toWChar." << endl;
			break;
		case FAILED_CONVERTCHARSET:
			cout << "Failed convertCharset." << endl;
			break;
		case FAILED_OPENCLIPBOARD:
			cout << "Failed OpenClipboard." << endl;
			break;
		default:
			break;
	}
	
	return 0;
}

static int toClip(int num, char *argv[]){
	
	if (num != VALID_TOCLIP_ARG_NUM)
		return INVALID_ARG_NUM;
	
	wchar_t *dispText;
	if (!toWChar(CP_ACP, *(argv + 2), &dispText))
		return FAILED_TOWCHAR;
	
	const int startHtmlPosition = strlen(HEAD_START_HTML) + strlen(HEAD_END_HTML) + strlen(HEAD_START_FRAGMENT) + strlen(HEAD_END_FRAGMENT) + strlen(HEAD_LAST) + PAD_NUM * 4;
	
	char *fragment = (char *)malloc((strlen(HTML_HEAD) + strlen(*(argv + 1)) + strlen(*(argv + 2)) + strlen(*(argv + 3)) + strlen(HTML_TAIL)) * sizeof(char));
	sprintf(fragment, "%s%s%s%s%s", HTML_HEAD, *(argv + 1), *(argv + 2), *(argv + 3), HTML_TAIL);
	
	const int startFragmentPosition = startHtmlPosition + strlen(START_FRAGMENT);
	const int endFragmentPosition = startFragmentPosition + strlen(fragment);
	const int endHtmlPosition = endFragmentPosition + strlen(END_FRAGMENT);
	
	char *html = (char *)malloc(endHtmlPosition * sizeof(char));
	sprintf(html, "%s%s%s%s%s%s%s%s%s%s%s",
		HEAD_START_HTML,
		padLeft(startHtmlPosition, PAD_NUM),
		HEAD_END_HTML,
		padLeft(endHtmlPosition, PAD_NUM),
		HEAD_START_FRAGMENT,
		padLeft(startFragmentPosition, PAD_NUM),
		HEAD_END_FRAGMENT,
		padLeft(endFragmentPosition, PAD_NUM),
		HEAD_LAST,
		START_FRAGMENT,
		fragment,
		END_FRAGMENT);
	
	char *htmlUtf8;
	if (!convertCharset(CP_ACP, CP_UTF8, html, &htmlUtf8))
		return FAILED_CONVERTCHARSET;
	
	if(!OpenClipboard(0))
		return FAILED_OPENCLIPBOARD;
	
	EmptyClipboard();
	
	//text to clipboard
	size_t textSize =  (wcslen(dispText) + 1) * sizeof(wchar_t);
	HGLOBAL textData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, textSize);
	memcpy((wchar_t *)GlobalLock(textData), dispText, textSize);
	SetClipboardData(CF_UNICODETEXT, textData);
	GlobalUnlock(textData);
	GlobalFree(textData);
	
	//html to clipboard
	HGLOBAL htmlData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, strlen(htmlUtf8));
	strcpy((char *)GlobalLock(htmlData), htmlUtf8);
	SetClipboardData(RegisterClipboardFormat("HTML Format"), htmlData);
	GlobalUnlock(htmlData);
	GlobalFree(htmlData);
	
	CloseClipboard();
	
	free(dispText);
	free(fragment);
	free(html);
	free(htmlUtf8);
	
	return SUCCESS_TOCLIP;
}

static bool convertCharset(int fromCP, int toCP, const char *source, char **dest)
{
	wchar_t *sourceWChar;
	
	if (!toWChar(fromCP, source, &sourceWChar))
		return false;
	
	int mByteLen = WideCharToMultiByte(toCP, 0, sourceWChar, -1, NULL, 0, NULL, NULL);
	if (mByteLen <= 0)
		return false;
	
	*dest = (char *)malloc(mByteLen * sizeof(char));
	WideCharToMultiByte (CP_UTF8, 0, sourceWChar, -1, *dest, mByteLen, NULL, NULL);
	
	return true;
}

static bool toWChar(int fromCP, const char *source, wchar_t **dest)
{
	int wCharLen = MultiByteToWideChar(fromCP, 0, source, -1, NULL, 0);
	if (wCharLen <= 0)
		return false;
	
	*dest = (wchar_t *)malloc(wCharLen * sizeof(wchar_t));
	MultiByteToWideChar(fromCP, 0, source, -1, *dest, wCharLen);
	
	return true;
}

static char *padLeft(long long num, int pad_num) {
	int target_pad_num = pad_num;
	int num_digit = 0 <= num ? log10(num) + 1 : log10(-num) + 1;
	if (num_digit < 1)
		target_pad_num = 1;
	else if (target_pad_num < num_digit)
		target_pad_num = num_digit;
	
	char *pad = (char *)malloc(target_pad_num * sizeof(char));
	sprintf(pad, "");
	
	if (num_digit < 1)
		return pad;
	
	int i;
	for (i = 0; i < target_pad_num - num_digit; i++)
		sprintf(pad, "%s%s", pad, "0");
	
	char *result = (char *)malloc(target_pad_num * sizeof(char));
	if (0 <= num)
		sprintf(result, "%s%lld", pad, num);
	else
		sprintf(result, "-%s%lld", pad, -num);
	
	return result;
}


コマンドプロンプトで、保存したファイルのディレクトリまで移動
13.png

以下のコマンドを入力
g++ ファイル名.cpp -o 任意の名前
14.png

保存先に任意のファイル名.exeが作成されていることを確認する
15.png

④プログラムの実行
基本的にはVisual Basicのものと同じ使い方
第1引数にHTML開始タグ、第2引数に囲むテキスト、第3引数にHTML終了タグ
を入力してEnter。
例) testProgram.exe "<a href=\"https://www.google.co.jp/\">" "HTML テスト" "</a>"


以上。

nice!(0)  コメント(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Raspberry Pi(Raspbia..Rocksmith 2014 Remas.. ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。