27 件 見つかりました。
libpngとzlibを使ってVC++(non MFC)でプログラムを書こうと思った。(VS.NET 2003)
まずはライブラリをコンパイルする。libpng-1.2.22-no-config.tar.gzとzlib-1.2.3.tar.gzをダウンロードした。展開し、zlibの内容をlibpngと「兄弟」となるように配置(例えばC:\temp\libpng\(libpngの中身)、C:\temp\zlib\(zlibの中身))。で、(libpng)\projects\visualc71\libpng.sln を開き、ビルド => 構成マネージャから LIB Release を選んで、ビルドするとライブラリができる。このあたりは (libpng)\projects\visualc71\README.txt に書いてある。Win32_LIB_Releaseディレクトリのlibpng.lib、zlib.libを、またソースファイルからpng.h、pngconf.h、zlib.h、zconf.hを持ってくれば使用準備は整う。
さてプログラムを書いてビルドしたらば、「競合」によって失敗した。内容から解決法まで、下記と同様であった。
2006-10-26 - 王様の箱庭::blog
エラーは下記のようなものである。プロジェクトのプロパティから C/C++ => コード生成 => ランタイムライブラリ を「マルチスレッドDLL」にすることでエラーは消えた。なぜうまくいったかは理解していない。
... step1 error LNK2005: _abort は既に LIBC.lib(abort.obj) で定義されています。 ... step1 fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。 step1 warning LNK4098: defaultlib 'MSVCRTD' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
プログラムからショートカットを作成する方法について以前メモしたが、Linuxで処理する時などに備えファイルフォーマットそのものを知りたいと思った。
だが道のりはそれほど簡単ではないようで、「公式なドキュメントは無いようだ」との見解を見つけた。
xe-kodo(2006-08-29)
参考になるのは以下あたりか。
(rc*) ロミテチオ・ログ: .lnk ファイル解析
http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf
私はプレゼン用スライドなど諸書類はIllustratorで準備することが多い。
で、仕事柄以下の様な形式の論文参照テキストオブジェクトを頻繁に用いる。
Itoh et al., Appl. Phys. Lett. 83, 2043 (2003)
この文字列自体は別途作成した論文整理ソフトから容易にクリップボードにコピーしIllustratorにペーストできる。ペースト自体はすぐ終わるが、上で「83」となっているvolume番号は太字で表記したいので、ペーストの度に手作業でここを太字に直す作業が発生する。これが意外と面倒なので、何とかして一発で太字入りテキストオブジェクトを作成したいと思った。
こういうことはJavascript(参考:【Illustrator CS自動化作戦】)とかCOMインターフェースとかIllustrator SDKを用いるのが正攻法で、手間も小さいだろう。でもクリップボードに(ただの文字列ではなく)Illustratorが解釈できるデータを用意し、それをペーストするというアプローチも面白そうだなと思った。開発は面倒そうだが概念的には明瞭で既存のペーストコマンドから実現できるし、またIllustratorに頼らずIllustratorのオブジェクトが作れれば、今後何かと便利かもしれない。
古くはAICBという形式が使われていたようだが、現在はPDF形式がメインのようである。というわけでPDF形式が良さそうだが、勉強すべき事項は多く、しばらくはトライ&エラーの体当たりな開発が必要そうだ。そこでとりあえず、PDF形式でのペーストを行うためだけのプログラムを書いた。これはクリップボードにコピーしたテキスト形式のデータを、PDF形式として無理矢理解釈しているだけである。これを用いて、メモ帳相手にひたすら手書きPDFを作成しながらIllustratorペーストした際にどのようになるかを調べれば、だんだん形式への理解も深まるのではと思う。たぶん。
#include <windows.h> #include <tchar.h> static HGLOBAL PrepareClipboardTextData(char* buf){ HGLOBAL hMem = GlobalAlloc(GHND | GMEM_SHARE, lstrlenA(buf)); if(!hMem) return NULL; char* buf2 = (char*)GlobalLock(hMem); lstrcpyA(buf2, buf); GlobalUnlock(hMem); return hMem; } UINT ConvertClipboardTextIntoPDF(){ try{ if(!OpenClipboard(NULL)) return 1; const UINT cf_pdf = RegisterClipboardFormat(TEXT("Portable Document Format")); if(cf_pdf == 0) throw 2; char* buf = (char*)GetClipboardData(CF_TEXT); if(!buf) throw 3; HGLOBAL hMem = PrepareClipboardTextData(buf); if(!hMem) throw 4; if(!SetClipboardData(cf_pdf, hMem)) throw 5; } catch(UINT i) { CloseClipboard(); return i; } CloseClipboard(); return 0; } int WINAPI _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */){ const UINT err = ConvertClipboardTextIntoPDF(); if(err){ MessageBox(NULL, TEXT("failed"), TEXT("hiConvertClipboardTextIntoPDF"), MB_ICONEXCLAMATION); } return 0; }
[2007-01-18-01]や[2007-01-19-01]に書いたがやっぱりリンク付きPDFは便利(プレゼンなどで)。
Javascriptでもいじれるみたいだが、残念ながら上書きのみのようで、完全に制御するにはSDKでプラグイン作るレベルまで行かないとダメのようだ。
しかし実際にリンクを貼る作業をIllustrator上でどうやって実現すればいいのだろう?
現在の妄想:
__HILINK__(ファイル名、しおり名)といったテキストオブジェクトを、ファイル名やしおり名へのリンクに変換するようにすれば良いのでは?ととりあえず思ってる。クリッカブルな領域は、縦横比に捕われず自由変形できるテキストオブジェクトが占める領域で指定するようにすればどうだろう。
以下のような感じで動いているようだ。(tchar.hは直接は関係ない)
#include <io.h> #include <tchar.h> inline BOOL DoesFileExist(LPCTSTR path){ return _taccess(path, 0)==0; }
ちょっとSusieプラグインを作ってみようと思った。この時ビルドするのはDLLだが、使用にあたっては拡張子をspiに変更する必要があり、これをいちいち手動でリネームするのは面倒くさい。自動化するにはプロジェクトのプロパティからビルドイベント => ビルド後のイベントと辿ってコマンドラインに以下を入力(リネーム後のファイル名としてパスを含めていないことに注意。これはrenameコマンドの仕様)。
rename $(OutDir)\$(TargetFileName) $(TargetName).spi
rename Release\myproj.dll myproj.spi
例えばMFCでダイアログベースにし、その上にボタンやリストビューなどのコントロールを配置し、かつダイアログのOnMouseMoveイベント(WM_MOUSEMOVE)で何かする(マウスカーソル座標表示など)ようにしたとする。この時コントロール上でマウスカーソルを動かしても、ダイアログのOnMouseMoveは実行されない。というのはWM_MOUSEMOVEはコントロールのウィンドウに送られるからである。
コントロール上でマウスの動きを捉えるには、真っ当にはコントロールのクラスを派生して自前でWM_MOUSEMOVEの処理を記述することである。が、ドラッグアンドドロップや単純な座標検出などの作業などにはこいつは大袈裟すぎる。そんな時はCWnd::SetCapture() (::SetCapture(HWND)でもいいけど) するとよい。これの呼出し後は「カーソルの位置に関係なく、以降のすべてのマウス入力が現在の CWnd オブジェクトに送信されます。」(MSDN) 終わったらReleaseCapture()する。
以下は簡単な例。ダイアログ上のクリックでCapture状態が入れ替わる。マウスカーソルの座標がウィンドウ左上に表示される。Capture時はダイアログ上あらゆる場所でのカーソルの座標が更新されるが、そうでない通常時はコントロール上のカーソルの動きは無視される。当然、Capture時にボタンのクリックなどコントロールにマウスイベントを送ることはできない。
void CMyDlg::OnMouseMove(UINT nFlags, CPoint point) { CString str; str.Format("x:%d y:%d", point.x, point.y); GetDC()->TextOut(0, 0, str); CDialog::OnMouseMove(nFlags, point); } void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point) { static bool b = true; if(b) SetCapture(); else ReleaseCapture(); b = !b; CDialog::OnLButtonDown(nFlags, point); }
py2exeというのが、pythonスクリプトをWindows実行形式に変換してくれるプログラムのようだ。すげー
私はダウンロードした実行ファイルをまず展開してインストール方法がわからずムカツいたが、単に実行ファイルを実行するだけでインストールは即座に終わった。
実際に変換するには
from distutils.core import setup import py2exe #setup(console=["aaa.py"]) # 実行時dos画面が出る setup(windows=["aaa.py"]) # 実行時dos画面が出ないなるsetup.pyを用意した上で
python setup.py py2exeとする。するとdistディレクトリ内にexe本体を含めた配布用ファイル一式が出来上がる。配布にあたってはこれらをまとめて配布する必要がある。
ちょっとしたGUIプログラムをパッと作りたい時にどうするか。
C/C++はちょっとやるだけには面倒なので、もっと何も考えないでいいやつにしたい。
Visual Basicは文法面がちょっと気にくわない。.NETはよくわからない。
じゃあスクリプト言語でということになるが、何かと文書やツール類が充実してるpythonが良さそう。
で、WindowsでpythonをGUIから使う/呼ぶためにはどうすればいいのか調べたことをメモする。
まずwxWidgetsというものがある。これは言語やOSの違いを吸収してくれるGUIツールキット。これをpythonからいじるためのものがwxPythonである。これが「pythonでGUI」に必要な条件(他のツールキットももちろんある)。
で、GUI設計においてはデザイナの使用がキモなので、このためのツールを探した。そしてwxGladeなるものとXRCedなるものを発見した。
前提(サイザー)
wxWidgetsにおいてはサイザーなるオブジェクトがある。これはウィンドウと各コントロールの相対的な大きさや位置関係をよしなに面倒見てくれるオブジェクト。wxWidgetにおいては、コントロールの配置はサイザーの使用が原則のようだ。wxGladeではサイザーが無いとコントロールが配置できない。XRCedではできるみたい。
wxGlade
これはコントロールを比較的直観的に、つまりはVisual Studioのように配置できるため、画面などもそこそこ見慣れたものが出てくる。GUIの情報の出力形式はXRC(後述)、python、C++など色々と選べる。インストーラでインストールできた。
wxWidgets でクロスプラットフォーム GUIアプリを作ろう
XRCed
これはVisual Studioなどと比べ抽象的に(と感じた)コントロールを配置するもので、最初は面喰らったがサイザーの概念が多少わかるとこれはそれほど苦にならなかった。GUI情報の出力はXRCのみ。wxPythonで記述されており、wxPythonに付属。
PythonMatrix:XRCedの使い方
ちょっと触っただけだが、どちらも優れていて使い易そうだなと感じた。だが、wxGladeは複数の出力形式ができ、イベントハンドラ名の記述もできる点で優れているのかなあと感じた。GUI部分を変更して上書き保存しても、ハンドラの定義部分はうまく残してくれるようだ。
順番は前後したが、wxPythonにおいてGUIの記述は2通りある:ソースに直接コントロールの配置など全て記述するのと、GUI情報のみXMLファイルに格納し(これをXRCというようだ)別途読み込むこと。前者はソースひとつで完結する単純明瞭さがメリットで、後者はインターフェースと処理のロジックを分離できるのがメリット。
wxGladeでハンドラを指定してpython形式で出力するとハンドラの記述も終わっていて便利。一方でXRCで出力すると、後に別途自分でpythonソースにハンドラを記述(「このボタン押下時この関数を呼べ」)する必要があってひと手間増える(GUIとソースの分離がXRCの本質なので、まあこれは当然)。XRCedは出力がXRCなので、当然同様な事情である。
パッと作成するシンプルさの観点からは、wxGladeを使用してpythonで出力するのが良さそうというのが今日の結論。
なお、XRCで記述したコントロールに対しイベントハンドラを記述するには以下のようにする。XRC Tutorial
<?xml version="1.0" encoding="cp932"?> <resource> <object class="wxFrame" name="myframe"> <title>myframe_title</title> <object class="wxPanel" name="mypanel"> <object class="wxBoxSizer"> <orient>wxVERTICAL</orient> <object class="sizeritem"> <object class="wxButton" name="mybutton"> <label>mybutton_label</label> </object> </object> </object> </object> </object> </resource>
import wx from wx import xrc class MyApp(wx.App): def OnInit(self): self.res = xrc.XmlResource('hoge.xrc') self.init_frame() return True def init_frame(self): self.frame = self.res.LoadFrame(None, 'myframe') self.panel = xrc.XRCCTRL(self.frame, 'mypanel') self.frame.Bind(wx.EVT_BUTTON, self.OnMyButton, id=xrc.XRCID('mybutton')) # wx.EVT_BUTTON(self, xrc.XRCID('mybutton'), self.OnMyButton) # also acceptable ?! self.frame.Show() def OnMyButton(self, evt): wx.MessageBox('hoge', 'fuga') if __name__ == '__main__': app = MyApp(False) app.MainLoop()