hirax.net::Keywords::「WindowsAPI」のブログ



2009-07-14[n年前へ]

「エクセルで電界シミュレーション」と「ウィンドウ半透明化マクロ」 

 「各種方程式を差分化する方法を学び、実際に表計算ソフトで電界シミュレーションと伝熱シミュレーションをできるようになろう」という講習会を手伝う準備をした。準備のひとつに、受講者の実習作業を前もってやってみる、というのがある。すると、どの部分がわかりにくいとか・難しいとかいったことがわかる。

 表計算ソフトで電界シミュレーションをする時に、「わかりにくい」と感じる部分のひとつが、複合誘電体の電界計算だ。差分化の仕方と、その差分化されたものを表計算ソフトへどのように実装するかにもよるが、今行っている実習では複合誘電体の電界計算部分に、わかりにくい部分がある。

 その実習では、ポワソン方程式を解くために、エクセルの3つのワークシートを使う。電位を計算するシート・空間の各領域における誘電率分布を入力するシート・空間の各領域における電荷分布を入力シート、という具合である。そして、わかりにくいのが、「電位分布シート」と、「誘電率分布シート」「電荷分布シート」、のセルの空間的な意味が少し異なる、ということだ。「電位分布シート」の各セルが空間上に一定長刻みで作られた各格子「点」を意味するなら、「誘電率分布シート」「電荷分布シート」では、各セルは格子で囲われた各領域を示すのである。各セルの意味合いが異なる結果、空間的な位置は、「電位分布シート」に対して「誘電率分布シート」「電荷分布シート」のセルは「半セル分」ずれることになる。そのズレが一番最初はわかりづらいのである。

 そこで、「Excel Hacks 第2版― プロが教える究極のテクニック140選」に載っていた「エクセルのVBAマクロからWindows APIを使い、エクセルのウィンドウを半透明化するテクニック」を使い、「電位分布シート」を開いたエクセルウィンドウを半透明化し、「誘電率分布シート」などと重ねて眺めてみることができるようにしてみた。それが、右上の画像と下の動画である。ひとつのファイルをふたつのエクセル(アプリケーション)から開いた状態で、「電位分布シート」を開いているエクセルでマクロを実行すると、「電位分布シート」の下に「誘電率分布シート」が透けて見える。そして、シート間の位置関係を正しく示すようにウィンドウを並べてやれば、各セルが示す「」場所のズレを体感できるだろう、というわけである。

 下の動画の場合は、「誘電率分布シート」には赤罫線がひいてあり、「電位分布シート」には青罫線をひいてある。そして、それらが半セルずれていることが体感できるようにしてみた。

 ちなみに、エクセルの半透明化マクロは、Windows API上の関数を定義した後に、

mywnd=FindWindow("XLMAIN", 
                 Application.Caption)
oStyle=GetWindowLong(mywnd,GWL_EXSTYLE)
SetWindowLong mywnd,GWL_EXSTYLE,
          oStyle Or WS_EX_LAYERED
SetLayeredWindowAttributes mywnd,0,
          (255*60)/100,LWA_ALPHA
という風にしてやることで、エクセルのアプリケーション・ウィンドウを半透明化させている。もしも、半透明化を戻したければ、
mywnd=FindWindow("XLMAIN",
         Application.Caption)
SetWindowLong mywnd,GWL_EXSTYLE,oStyle
というコードを実行すれば良い。それほど使う状況があるとは思いづらい"Excel Hack"だが、VBAマクロからWindows APIを叩けば、Excelからでも「どんなことでもできる」と思わせるサンプルとして、結構面白い。

エクセルVBAでウィンドウ半透明化






2009-07-15[n年前へ]

エクセルのワークシート・ウィンドウだけを半透明化することができるか? 

 「エクセルで電界シミュレーション」と「ウィンドウ半透明化マクロ」で、エクセルのアプリケーションウィンドウ全体を半透明化するマクロを使ってみた。しかし、やはり、「エクセルのアプリケーションウィンドウ全体を半透明化するのではなくて、エクセルのウィンドウの中で開いている特定のワークシートだけを半透明化したい」と感じるに違いない。

 それなら、「エクセルで電界シミュレーション」と「ウィンドウ半透明化マクロ」で使ったVBAマクロの下記の部分を(もちろんWin32 API 関数は定義した上で)、

mywnd=FindWindow("XLMAIN", 
                 Application.Caption)
(たとえばExcel 2003なら)次のように書き換えてやれば良いように思える。
mywnd=FindWindow("XLMAIN", 
                  Application.Caption)
mywnd=FindWindowEx(mywnd,0,"XLDESK",
                   vbNullString)
mywnd=FindWindowEx(mywnd,0,"EXCEL7",
                    ActiveSheet.Name)

 しかし、これは実際には動かない。なぜなら、半透明化=WS_EX_LAYEREDは「親ウィンドウ」しかサポートしていないからである。たとえば、MSDNのWindow Featuresには、

 Note that WS_EX_LAYERED cannot be used for child windows.
とある。つまり、エクセルのアプリケーション・ウィンドウの孫ウィンドウであるワークシート・ウィンドウだけを半透明化させることは(現状では)できない、ということになる。

2009-07-29[n年前へ]

wincom.rbのCOM10以上対応 

 以前、スレッドを使い、Rubyでシリアル通信をするクラスComThreadを書きました。このクラスは、wincom.rbを利用しています。

 少し前、wincom.rbが、COM10以上の番号のシリアル・ポートを開けないことに気づきました。ソースを眺め調べてみると、WindowsAPIのCreateFile()を使った場合の、COM10 以上のシリアルポートを指定方法に沿っていないことが原因でした。対処としては、wincom.rbの71行目を

comno = "\\\\.\\COM#{icomno}\0"
というように変えれば、COM10以上のポートにも(もちろんCOM10以下のポートにも)対応するようになります。

 最近の(各種I/Fがたくさん備えている)PCに、USB接続のシリアルポートI/Fを繋いだ場合、自動的にCOM10以上になる場合も多いと思います。そんな状況下で、wincom.rbを使うためのTipsとして、ここにメモを書いておきます。



■Powered by yagm.net