ハードなソフトの話

アクセスカウンタ

zoom RSS さらにコマンドライン用クリップボードツールを作ってみた(MinGW g++編)

<<   作成日時 : 2009/05/13 23:35   >>

驚いた ブログ気持玉 1 / トラックバック 0 / コメント 0

強いて言えば、3年前に書いた「続・コマンドライン用クリップボードツールを作ってみた(Active Perl編)」の続編である。

実はUSBメモリで持ち歩きたいのでインストールしなくても単独のEXEで動作してほしい。

最近までコマンドライン用クリップボードツールをPerlで書いていた。PerlExeを使ってもPARを使ってもEXE化するとファイルサイズが2MBを超えた。気が滅入る。Tcl/TkのeTclやStarkitも考えてみたが似たようなサイズだった。

1GBのUSBメモリがスーパーマーケットの安売りコーナーで買えるんだから気にしなくてもいいかもしれない。
しかし、仕事の都合で1GBのUSBメモリを1個しか使えないのでサイズは小さいに越したことはない。
さらに、サイズが大きいと起動時間が遅くなる。これはコマンドラインツールではあまり嬉しくない。
実行環境はWindowsだけであるが、まれにWindows 2000のPCを使うこともあり、.Net Frameworksにも、あまり頼りたくない。

そんなわけで、MinGWのGnu C++でコマンドライン用のクリップボードツールを作ることにした。

当面の目標はWindows Server 2003やWindows Vistaに付属している Clip.exe と同程度の機能を実現することにある。

MinGWのインストールについては特に触れない。1番簡単な方法は、Strawberry Perl の最新版をインストールすることである。最新版はWindows Vistaでも問題なく動作する。

突っ込みどころ満載だが、Googleをマニュアル代わりに1時間半ほど、コピー&ペーストを繰り返したら、いちおう使えそうなプログラムが書けた。
#include <windows.h>
#include <stdio.h>

int const MAXLINE=1024;

char* gets_if(char* ret, char* buf);
HGLOBAL addString(HGLOBAL hText, char* p, int* pTextsize);
void CB_setText(HGLOBAL hText);

int main(){
  int  textsize = 0;
  char buf[MAXLINE];
  HGLOBAL hText = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,0);

  memset((void *)buf,0,sizeof(buf));
  while(gets_if(fgets(buf,MAXLINE-1,stdin),buf)){
    hText = addString(hText,(char *)buf,&textsize);
    memset((void *)buf,0,sizeof(buf));
  }

  CB_setText(hText);
}

char* gets_if(char* ret, char* buf ){
  int len = strlen(buf);
  if ( len == 0 ) return ret;
  if ( buf[len-1] == '\n' ){
    buf[len-1] = 0;
    strcat(buf,"\r\n");
    // printf("changed %02x,%02x\n",buf[len-1],buf[len]);
    len = strlen(buf);
  }
  if ( ret ) return ret;
  if ( buf[len-1] != '\n' ) return buf;
  return NULL;
}

HGLOBAL addString(HGLOBAL hText, char *p, int *pTextsize){
  int iOffset = *pTextsize;
  *pTextsize  = *pTextsize+strlen(p)+1;
  HGLOBAL hNewText = GlobalReAlloc(hText,*pTextsize,GMEM_ZEROINIT);
  char *pText = (char *)GlobalLock(hNewText);
  strcat(pText,p);
  GlobalUnlock(hNewText);
  return hNewText;
}

void CB_setText(HGLOBAL hText)
{
  OpenClipboard(NULL);
  EmptyClipboard();
  SetClipboardData(CF_TEXT, hText);
  CloseClipboard();
}

このプログラムはclipi.cppとした。コンパイルはおなじみの方法で次の通り:
g++ clipi.cpp -o clipi

exeのサイズは20KB弱ででほぼ100分の1になる。かなり小さい。
使い方はClip.exeと同じである。Windows XPにはClip.exeがないので少しは役に立つかもしれない。
機能的にほぼ同等だが、次の機能が欠けている。
  • clipiとコマンドのみを入力すると標準入力モードになる。
    Clip.exeではメッセージが表示される

  • ヘルプの表示機能が存在しない
  • 英語モードのとき英語でヘルプを表示しない

日本のWindowsしか使わない人には関係ないが、コードページが英語になっているのに堂々と日本語メッセージを表示するプログラムはかなりムカつく。

C++で書いたといっても現状ではBetter Cである。久しぶりにC言語でプログラムを書いたが文法で悩むことはなかった。やはり、10年以上も使い続けていた言語だけのことはある。WindowsのAPIもWindows 2.Xのプログラミングで使用していたものが現在でもそのまま使えた。Windowsの外観は変わったもののAPIの互換性は健在なようだ。

ある程度のレベルに達したら、どっかにマニュアル付きでアップロードするけど、いつになることやら…。

テーマ

関連テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ
気持玉数 : 1
驚いた

トラックバック(0件)

タイトル (本文) ブログ名/日時

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
さらにコマンドライン用クリップボードツールを作ってみた(MinGW g++編) ハードなソフトの話/BIGLOBEウェブリブログ
文字サイズ:       閉じる