全然更新しないブログ
HSPメモ帳
ファイルのドラッグアンドドロップ
「ドラッグアンドドロップ」
- 1.最初に、ウィンドウをドロップに対応させます。
- 「shell32.dll」の「DragAcceptFiles」関数を使用します。
DragAcceptFiles hwnd, fAccept
第一引数:ドラッグアンドドロップを受け入れるウィンドウハンドル
第二引数:0:受け入れません 1:受け入れます
- 2.ウィンドウプロシージャで、「WM_DROPFILES」(0x0233)メッセージを取得します。
- HSP3の例)
oncmd *DropFiles,0x0233
wparam: hDrop
lparam: 使用せず
- 3.メッセージが来たときに処理をします。
- 「shell32.dll」の「DragQueryFile」関数でファイル名を取得します。
DragQueryFile hDrop, iFile, ipszFile, cch
第一引数:ファイル名を保持している構造体(後に解放必要)
第二引数:ファイルのインデックス番号
第三引数:ファイル名を取得するバッファ
第四引数:第三引数のバッファサイズ
- 4. 3でのhDropを解放します。
- 「shell32.dll」の「DragFinish」で解放します。
DragFinish hDrop
第一引数:3の第一引数を指定。
サンプル |
//////////////////////////////////////////////////////////////////// //定義 #define WM_DROPFILES 0x0233 //////////////////////////////////////////////////////////////////// //関数登録 #uselib "shell32.dll" #cfunc DragQueryFile "DragQueryFileA" int,int,sptr,int #func DragAcceptFiles "DragAcceptFiles" int,int #func DragFinish "DragFinish" int //////////////////////////////////////////////////////////////////// //メイン screen 0,300,300 DragAcceptFiles hwnd,1 oncmd gosub *DROPFILES, WM_DROPFILES stop //////////////////////////////////////////////////////////////////// //ドラッグアンドドロップ *DROPFILES sdim s,260 sdim files,1024 ret=DragQueryFile(wparam,-1,varptr(s),256) if ret!=-1{ files="総数:"+ret repeat ret ret=DragQueryFile(wparam,cnt,varptr(s),256) files+="\n"+ret+": "+s loop } DragFinish wparam dialog ""+files return |
コメント ( 0 ) | Trackback ( 0 )
NTPによる時刻取得
「NTPによる時刻取得」
- NTP(Network Time Protocol)
- ネットワークを介して時刻調整をするプロトコル。
サーバは、GPSや原子時計等を利用して正確な時刻を取得しています。
ポートは、123でUDPを使用。 - 使用例
- Ws2_32.dllを使用します。
- 「WSAStartup」で通信の初期化
- 「socket」でソケット作成
- 「inet_addr」「gethostbyname」でホスト情報取得
- 「connect」で接続
- 「WSAAsyncSelect」で非同期通信
- 「send」で、NTP_Packetを送信
最初の4バイトに、数値11を指定。他は0。 - 「recv」で、NTP_Packetを受信
- 「WSAAsyncSelect」で非同期終了
- 「shutdown」で、送受信を停止
- 「closesocket」でソケット解放
- 「WSACleanup」でリソース解放
NTP_Packet (48Byte) 位置 長さ 名称 説明 0 2bit LI
閏秒指示子閏秒の分について
0:警告なし
1:最後の分は61秒
2:最後の分は59秒
3:同期していない2bit 3bit VN
バージョン番号バージョン番号
3:NTPサーバ(IPv4)
4:SNTPサーバ(IPv4 IPv6)5bit 3bit mode
モードモード
3:クライアント
4:サーバ8bit 8bit Stratum
階級ローカル時計の階級
0:既定なし
1:一次基準源(GPS等)
2-15:NTPやSNTP経由
16-255:予約済み16bit 8bit Poll
ポーリング間隔連続するメッセージ間の最大間隔
(2のべき乗の秒数)24bit 8bit Precision
精度時刻の精度
(2のべき乗の秒数)4Byte 4byte Root Delay
ルート遅延一次基準源までの往復の遅延の合計秒
15bit-16bitに少数値8Byte 4Byte Root Dispersion
ルート分散一次基準源との誤差秒数
15bit-16bitに少数値12Byte 4Byte Reference Identifier
基準IDIPアドレス、又は文字列 16Byte 8Byte Reference Timestamp
基準タイムスタンプ現在時間 24Byte 8Byte Receive Timestamp
受信タイムスタンプサーバに要求が届いた時間 32Byte 8Byte Transmit Timestamp
送信タイムスタンプサーバからクライアントに送られた時間 40Byte 4Byte transmit_timestamp_seconds ローカルタイム 44Byte 4Byte transmit_timestamp_fractions ミリセカンド
サンプル NTPを使用して、5秒ごとに時刻を取得して表示しています。 |
///////////////////////////////////////////////////////// //定義 #define PORT 123 #define SOCK_DGRAM 2 #define AF_INET 2 //FD_READ(0x01) FD_WRITE(0x02) FD_CONNECT(0x10) FD_CLOSE(0x20) #define FD_MESSAGE 0x33 #define FD_EVENT 0x5000 #define WM_TIMER 0x0113 #define WM_CLOSE 0x0010 #define ID_TIMER 0x6000 ///////////////////////////////////////////////////////// //関数の登録 #uselib "Ws2_32.dll" #cfunc WSAStartup "WSAStartup" int , sptr #cfunc socket "socket" int,int,int #cfunc inet_addr "inet_addr" sptr #cfunc gethostbyname "gethostbyname" sptr #cfunc connect "connect" int,sptr,int #cfunc send "send" int,sptr,int,int #cfunc recv "recv" int,sptr,int,int #cfunc WSAAsyncSelect "WSAAsyncSelect" int,int,int,int #func shutdown "shutdown" int,int #func closesocket "closesocket" int #func WSACleanup "WSACleanup" #cfunc WSAGetLastError "WSAGetLastError" #cfunc htons "htons" int #cfunc ntohl "ntohl" int #uselib "crtdll.dll" #func time "time" sptr #cfunc localtime "localtime" sptr #cfunc asctime "asctime" sptr #uselib "kernel32.dll" #func SetLocalTime "SetLocalTime" sptr #uselib "user32.dll" #cfunc SetTimer "SetTimer" int,int,int,sptr #cfunc KillTimer "KillTimer" int,int ///////////////////////////////////////////////////////// //メイン screen 0,300,120 title "NTP サンプル":font "",12 color : boxf : color 255,255,255 sdim host,260 sdim hostname,260 dim tflag : tflag=0 host="eric.nc.u-tokyo.ac.jp" hostname=host pos 0,0:input host,250,20 pos 250,0:objsize 50,20 button gosub "変更",*hostchange pos 0,20 :objsize 300,20 button gosub "時刻設定",*SetTime ///////////////////////////////////////////////// //初期化 sdim WSAData,400 ret=WSAStartup(0x0101, varptr(WSAData)) if ret!=0{ gosub *closesoc dialog "WSAStartup error",,"stop" stop } ///////////////////////////////////////////////// //サーバーに接続 gosub *SVconnect ///////////////////////////////////////////////// //Window メッセージ oncmd gosub *FDEVENT,FD_EVENT oncmd gosub *closesoc,WM_CLOSE oncmd gosub *TIMER,WM_TIMER stop ///////////////////////////////////////////////////////// //WSAAsyncSelect *FDEVENT ///////////////////////////////////////////////// //最初に作成したsocのメッセージの場合 if wparam==soc{ ///////////////////////////////////////// //lparam上位ワードが0以外ではエラー if lparam>>16==0{ ///////////////////////////////// //ret:lparam下位ワード(メッセージの種類) ret=lparam&0xffff switch ret ///////////////////////////////// //recv case 0x0001 //FD_READ gosub *SVrecv swbreak ///////////////////////////////// //closesocket case 0x0020 //FD_CLOSE gosub *closesoc swbreak ///////////////////////////////// //デフォルト default swbreak swend } } return ///////////////////////////////////////////////////////// //ソケット作成 *SVsocket ///////////////////////////////////////////////// //ソケットの作成 UDP soc=socket(AF_INET, SOCK_DGRAM, 0) if soc == 0{ gosub *closesoc dialog "socket error",,"stop" stop } return ///////////////////////////////////////////////////////// //サーバーに接続 *SVconnect ///////////////////////////////////////////////// //ソケット作成 gosub *SVsocket ///////////////////////////////////////////////// //サーバーアドレス取得 dim svaddr sdim hostent, 16 svaddr=inet_addr(varptr(hostname)) if svaddr==-1{ ret=gethostbyname(varptr(hostname)) if ret{ dupptr svaddr,ret+12,4 dupptr ret,svaddr,4 dupptr svaddr,ret,4 } else{ gosub *closesoc dialog "gethostbyname error" return } } ///////////////////////////////////////////////// //接続 sdim sockaddr, 16 wpoke sockaddr, 0, AF_INET wpoke sockaddr, 2, htons(PORT) lpoke sockaddr, 4, svaddr if connect(soc, varptr(sockaddr), 16)==-1{ gosub *closesoc dialog "connect error" return } ///////////////////////////////////////////////// //非同期通信 ret=WSAAsyncSelect(soc,hwnd,FD_EVENT,FD_MESSAGE) if ret!=0:dialog "WSAAsyncSelect error",,"stop":stop ///////////////////////////////////////////////// //タイマー ret=SetTimer(hwnd,ID_TIMER,5000,0) return ///////////////////////////////////////////////////////// //送信 *SVsend ///////////////////////////////////////////////// //送信 dim NTP_SEND, 12 NTP_SEND(0) = 11;htonl(0x0B000000) ret=send(soc,varptr(NTP_SEND),48) if ret != 48{ gosub *closesoc dialog "send error" return } return ///////////////////////////////////////////////////////// //受信と時刻表示 *SVrecv dim NTP_RECV , 12 if recv(soc, varptr(NTP_RECV) ,48 ,0)==48{ dim t dim tm,9 redraw 0 color :boxf 0,40:color 255,255,255 ret=ntohl(NTP_RECV(10))-2208988800 dupptr tm,localtime(varptr(ret)),36 pos 50,50:tm(5)+=1900:tm(4)++ if tflag==1{ sdim systime,16 wpoke systime,0,tm(5):wpoke systime,2,tm(4) wpoke systime,6,tm(3):wpoke systime,8,tm(2) wpoke systime,10,tm(1):wpoke systime,12,tm(0) SetLocalTime(varptr(systime)) tflag=0 } mes "NTP時刻" mes strf("%02d/",tm(5))+strf("%02d/",tm(4))+strf("%02d",tm(3)) mes strf("%02d:",tm(2))+strf("%02d:",tm(1))+strf("%02d",tm(0)) time varptr(t) lag=t-ret ret=localtime(varptr(t)) dupptr tm,ret,36 pos 200,50:tm(5)+=1900:tm(4)++ mes "現在時刻" mes strf("%02d/",tm(5))+strf("%02d/",tm(4))+strf("%02d",tm(3)) mes strf("%02d:",tm(2))+strf("%02d:",tm(1))+strf("%02d",tm(0)) pos 50,100 mes "時刻差 : "+ lag +" 秒" redraw 1 } return ///////////////////////////////////////////////////////// //タイマー *TIMER gosub *SVsend return ///////////////////////////////////////////////////////// //ホスト変更 *hostchange ///////////////////////////////////////////////// //変更無しの場合 if hostname==host:return hostname=host gosub *closesoc gosub *SVconnect return ///////////////////////////////////////////////////////// //時刻設定 *SetTime tflag=1 gosub *SVsend return ///////////////////////////////////////////////////////// //通信終了 *closesoc ret=KillTimer(hwnd,ID_TIMER) shutdown soc,2 ret=WSAAsyncSelect(soc,hwnd,0,0) closesocket soc return ///////////////////////////////////////////////////////// //終了 *CLOSE gosub *closesoc WSACleanup return |
コメント ( 0 ) | Trackback ( 0 )
NTPによる時刻取得 2
「NTPによる時刻取得2」
接続先には近い場所を選びます。
サーバに負荷をかけないように注意が必要です。
- 接続先例
- 北海道大学 ntp.hokudai.ac.jp 133.87.1.18
- 東北大学 ntp.tohoku.ac.jp 130.34.11.117
- 東京大学 eric.nc.u-tokyo.ac.jp 130.69.251.23
- 愛知教育大学 ntp.auecc.aichi-edu.ac.jp 133.96.2.1
- 大阪大学 raicho.ime.cmc.osaka-u.ac.jp 133.1.84.1
- 山口大学 ns2.cc.yamaguchi-u.ac.jp 133.62.128.33
- 宮崎大学 clock.cc.miyazaki-u.ac.jp 133.54.240.28
- 琉球大学 geo.gen.u-ryukyu.ac.jp 133.13.144.124
- 参考サイト
- NTP - wiki@nohting
- NTPについて解説されています。
- Yoshi's Memo
- NTPについて解説されています。
- 福岡大のNTPサーバがアクセス集中で悲鳴
- サーバの状態や距離を考えてサービスを利用しましょう。
- 文書番号 : 875424
- マイクロソフト サポート情報
Windows Server 2003 で Windows 以外の
NTP サーバーとの同期が成功しない。
コメント ( 0 ) | Trackback ( 0 )
タスクトレイアイコンの作成
「タスクトレイアイコンの作成」
タスクトレイアイコンの作成
SHELL32.DLLの「Shell_NotifyIcon」関数を使用する事で、
タスクトレイに追加、変更、削除が可能となります。
Shell_NotifyIcon dwMessage , lpdata 動作環境 shell32.dll version 4.0以上 Windows NT 4.0, Windows 95以上 |
第一引数 dwMessage: 以下数値のどれか
|
第二引数 NOTIFYICONDATA 構造体のポインタ
Ver 4はここまで Ver 5はここまで Ver 6はここまで |
タスクトレイアイコンからメニューの表示
タスクトレイからのメニュー表示で、
気をつけないといけない点がいくつかあります。
- メニューを表示する前に
「SetForegroundWindow」で親ウィンドウをアクティブにすること
しない場合、親ウィンドウ、メニューを選択するまでメニューが消えません。
以下サンプルでは、タスクトレイ用の非表示ウィンドウを親ウィンドウとしています。 - メニューの表示終了後、「WM_NULL」をポストすること
しない場合、メニューが表示されないことがあります。
- 【参考リンク】
- MSサポート技術情報 文書番号 : 135788
- メニュー表示について
※日本語での説明ですが、翻訳がおかしい部分があるので
英語版のほうを参照したほうがいいかもしれません。 - MSサポート技術情報 文書番号 : 418138
- タスクトレイにアイコンが表示されない時
- WM_TIMERを使用して、3秒毎にshell32.dll内のアイコンを順番に表示しています。
システムアイコンを利用しているので、メモリ解放はしていません。
※通常アイコンを使用する場合解放を忘れるとメモリリークの原因になりますが、
システムで使用しているものを解放するとシステムが不安定になる事があるからです。
- クライアントエリアまたはタスクトレイアイコンを右クリックすることでメニューを表示します。
クライアントエリアの色変更と終了が可能です。
サンプル |
//////////////////////////////////////////////////////////////////////////////////// //関数登録 #uselib "Shell32.dll" #cfunc ExtractIcon "ExtractIconA" int,sptr,int #cfunc Shell_NotifyIcon "Shell_NotifyIcon" int,var #uselib "user32.dll" #cfunc CreatePopupMenu "CreatePopupMenu" #func InsertMenu "InsertMenuA" int,int,int,int,sptr #func TrackPopupMenu "TrackPopupMenu" int,int,int,int,int,int,int #func DestroyMenu "DestroyMenu" int #func SetForegroundWindow "SetForegroundWindow" int #func PostMessage "PostMessageA" int,int,int,int #func SetTimer "SetTimer" int,int,int,sptr #func KillTimer "KillTimer" int,int //////////////////////////////////////////////////////////////////////////////////// //定義 #define ICON_FILE dir_sys+"\\shell32.dll" #define WM_CLOSE 0x0010 //メッセージ:ソフト終了時 #define WM_RBUTTONDOWN 0x0204 //メッセージ:マウス右ボタンクリック #define WM_COMMAND 0x0111 //メッセージ:COMMAND #define WM_TIMER 0x0113 //メッセージ:タイマー #define WM_NULL 0x0000 //メッセージ:NULL #define NM_TRAYICON 0x5000 //メッセージ:トレイアイコン #define ID_TRAYICON 0x1000 //トレイアイコンの識別子 #define NIF_MESSAGE 0x01 //フラグ:メッセージの設定 #define NIF_ICON 0x02 //フラグ:アイコンの設定 #define NIF_TIP 0x04 //フラグ:ツールチップの設定 #define NIM_ADD 0x00 //タスクトレイに追加 #define NIM_MODIFY 0x01 //タスクトレイの変更 #define NIM_DELETE 0x02 //タスクトレイから削除 //////////////////////////////////////////////////////////////////////////////////// //メイン //////////////////////////////////////////////////////////////////////////// //タスクトレイ用ウィンドウ screen 1,300,200,2 hwnd1=hwnd //////////////////////////////////////////////////////////////////////////// //システムアイコンのハンドル取得 iconindex=0 hicon=ExtractIcon(hinstance,ICON_FILE,iconindex) //////////////////////////////////////////////////////////////////////////// //ツールチップ用変数 sdim tiptext,64 //////////////////////////////////////////////////////////////////////////// //NOTIFYICONDATA構造体(88バイト) dim icondata,22 icondata(0)=88 //NOTIFYICONDATA構造体のサイズ icondata(1)=hwnd1 //親ウィンドウ icondata(2)=ID_TRAYICON //アイコンの識別子 icondata(3)=NIF_MESSAGE|NIF_ICON|NIF_TIP //フラグ icondata(4)=NM_TRAYICON //親ウィンドウに通知される値 icondata(5)=hicon //アイコンのハンドル dupptr tiptext,varptr(icondata)+24,64,2 //ツールチップに表示する文字 tiptext="HSP タスクトレイサンプル\nアイコンインデックス:0" //////////////////////////////////////////////////////////////////////////// //タスクトレイにアイコンを追加 if Shell_NotifyIcon(NIM_ADD,icondata)==0:dialog "NIM_ADD error":end //////////////////////////////////////////////////////////////////////////// //タスクトレイのアイコン変更タイマー SetTimer hwnd1,1234,3000,0 //////////////////////////////////////////////////////////////////////////// //メッセージ割り込み oncmd gosub *TRAYICON,NM_TRAYICON oncmd gosub *TIMER,WM_TIMER //////////////////////////////////////////////////////////////////////////// //メインウィンドウ screen 0,300,200 title "タスクトレイサンプル" //////////////////////////////////////////////////////////////////////////// //メッセージ割り込み oncmd gosub *COMMAND,WM_COMMAND oncmd gosub *RBUTTONDOWN,WM_RBUTTONDOWN oncmd gosub *CLOSE,WM_CLOSE stop //////////////////////////////////////////////////////////////////////////////////// //メニュー表示 *menu hPopupMenu=CreatePopupMenu() InsertMenu hPopupMenu,0,0x400,0,"赤(&R)" InsertMenu hPopupMenu,1,0x400,1,"緑(&G)" InsertMenu hPopupMenu,2,0x400,2,"青(&B)" InsertMenu hPopupMenu,3,0x400,3,"終了(&Q)" TrackPopupMenu hPopupMenu,0x20,ginfo(0),ginfo(1),0,hwnd,0 DestroyMenu hPopupMenu return //////////////////////////////////////////////////////////////////////////////////// //トレイアイコンメッセージ *TRAYICON //////////////////////////////////////////////////////////////////////////// //右クリックされた時、ポップアップメニュー表示 if lparam==WM_RBUTTONDOWN{ SetForegroundWindow hwnd1 gosub *menu PostMessage hwnd1,WM_NULL,0,0 } return //////////////////////////////////////////////////////////////////////////////////// //クライアント上で右クリックした時 *RBUTTONDOWN gosub *menu return //////////////////////////////////////////////////////////////////////////////////// //メニュー処理 *COMMAND switch wparam & 0xffff case 0 color 255,0,0:boxf swbreak case 1 color 0,255,0:boxf swbreak case 2 color 0,0,255:boxf swbreak case 3 PostMessage hwnd,WM_CLOSE,0,0 swbreak default swbreak swend return //////////////////////////////////////////////////////////////////////////////////// //タスクトレイのアイコン変更タイマー *TIMER iconindex++ hicon=ExtractIcon(hinstance,ICON_FILE,iconindex) if hicon==0:iconindex=0:return icondata(3)=NIF_ICON|NIF_TIP icondata(5)=hicon tiptext="HSP タスクトレイサンプル\nアイコンインデックス:"+iconindex title "HSP タスクトレイサンプル INDEX: "+iconindex ret=Shell_NotifyIcon(NIM_MODIFY,icondata) return //////////////////////////////////////////////////////////////////////////////////// //終了時にアイコンを削除 *CLOSE KillTimer hwnd1 , 1234 if Shell_NotifyIcon(NIM_DELETE,icondata)==0:dialog "NIM_DELETE error" return |
コメント ( 0 ) | Trackback ( 0 )
タイトルバーの無いウィンドウを移動
「タイトルバーの無いウィンドウを移動」
メッセージを受け取った際、
タイトルバーをクリックしたかのように処理します。
サンプル1は、WM_NCHITTESTメッセージで、処理。
クライアント上でのマウス処理全てを変更していますので、
この方法では、WM_RBUTTONDOWN等のメッセージ処理はできません。
サンプル2は、WM_LBUTTONDOWNメッセージで処理。
◆サンプル
サンプル 1 |
///////////////////////////////////////////////// //定義 #define WM_NCHITTEST 0x0084 #define WM_KEYDOWN 0x0100 #define HTCLIENT 1 #define HTCAPTION 2 ///////////////////////////////////////////////// //関数登録 #uselib "user32.dll" #cfunc DefWindowProc "DefWindowProcA" int,int,int,int ///////////////////////////////////////////////// //メイン bgscr 0,300,50 font "",12 color:boxf:color 255,255,255:pos 10,10 mes "移動は、ウィンドウをドラッグして下さい" mes "何かキーを押すと終了します" oncmd gosub *NCHITTEST,WM_NCHITTEST oncmd *KEYDOWN,WM_KEYDOWN stop ///////////////////////////////////////////////// //最初のマウスメッセージ *NCHITTEST //既定のプロシージャを呼び出して ret=DefWindowProc(hwnd,WM_NCHITTEST,wparam,lparam) if ret==HTCLIENT{ //マウスが、クライアント内にある時 //タイトルバー上にあると見せかける return HTCAPTION } else{ //それ以外は既定を返します return ret } return ///////////////////////////////////////////////// //キー操作 *KEYDOWN end |
サンプル 2 |
///////////////////////////////////////////////// //定義 #define WM_LBUTTONDOWN 0x0201 #define WM_RBUTTONUP 0x0205 #define WM_NCLBUTTONDOWN 0x00A1 #define HTCAPTION 2 ///////////////////////////////////////////////// //メイン bgscr 0,300,50 font "",12 color:boxf:color 255,255,255:pos 10,10 mes "移動は、ウィンドウをドラッグして下さい" mes "右クリックで終了します" oncmd gosub *LBUTTONDOWN,WM_LBUTTONDOWN oncmd *RBUTTONUP,WM_RBUTTONUP stop ///////////////////////////////////////////////// //左クリックした時 DOWN *LBUTTONDOWN //非クライアント領域内(タイトルバー) //を左クリックさせる sendmsg hwnd,WM_NCLBUTTONDOWN,HTCAPTION,0 return ///////////////////////////////////////////////// //右クリックした時 UP *RBUTTONUP end |
コメント ( 0 ) | Trackback ( 0 )
« 前ページ |