Win32API質問箱 Build18
■ このスレッドは過去ログ倉庫に格納されています
0001 ◆Manna2uCLg
NGNGやさしいオジサマ達が、熱く暑く答えてくれよう。
でも最低限、最新スレくらいは質問する前に検索を。
過去スレ・参考は>>2-5くらいを参照するッス!
0239232
NGNGStretchDIBitsの時に表示していると思っていました。
TextOutと違い、ShowBitmapなどの名前でないのは、
その場で表示するわけではないからですね。
0240デフォルトの名無しさん
NGNG0241デフォルトの名無しさん
NGNGそうなる仕様でつ。
0242232
NGNGhdc = BeginPaint(hwnd, &ps);
for(y = 0; y < 10; y++)
for(x = 0; x < 10; x++)
ShowBitmap(hwnd, hdc, SHOW_BITMAP, y * 16, x * 16, 1, 1);
EndPaint(hwnd, &ps);
break;
こんな感じにしたら出来ました。
後、GetDCに変えてみると何回もWM_PAINTに行っているみたいで
CPU率がえらい事になっていましたが、return DefWindowProcを
defaultの所に書かずに関数の最後の所に書いたら直りました。
(どのイベントの時でもDefWindowProcを通るようにする)
しかし、ウィンドウズアプリケーションは難しすぎます。
いったいどのやり方でやるのが一番いいのでしょうか。
0243デフォルトの名無しさん
NGNGこういうやり方をするなら、フレームバッファを構築してそっちで書き換えた方がいいと思われ。
WM_PAINT内は、フレームバッファの内容をBitBltなどで展開するのみに徹した方がいい。
あと、ここまでやりたいのかどうかは知らないけど、途中で画像を書き換えたい場合は、
WM_PAINTメッセージを起こすのではなくGetDCを取得して張り付ける方がいい。
これで、大分負担は減るんじゃないかな。
しかしながら、CPU使用率を考えるくらいなら、まずWindowsプログラムを覚えることを
優先した方がいいんじゃない?
0245デフォルトの名無しさん
NGNGウィンドウが一つのときは大丈夫だと思うのですが。
0246デフォルトの名無しさん
NGNG0247245
NGNGええとそういう事ではなくて。説明不足ですね。
WinMainで"hoge"と"foo"という2つのウィンドウを作ったとき、
どちらのウィンドウにイベントが起こっても同じコールバック関数で
受け取るので、そのときHWNDが"hoge"のHWNDか"foo"のHWNDかを
判断したいのです。
例えばif(strcmp(CheckHWND(hwnd),"hoge")==0)みたいな感じです。
0248デフォルトの名無しさん
NGNG0249デフォルトの名無しさん
NGNGちょっと考えれば解ると思うが、あんたの方法だと、何らかの方法でイベントの発生したウィンドウのHWNDを得なければならない。
で、「イベント」とはなんだ?
0251245
NGNG何ならできますか。
>>249
イベントとは左クリックとかのWM_**です。
実はひとつのウィンドウ毎にひとつのコールバック関数を作るもの
なんですかね。myProg.lpszClassNameとCreateWindowの第一引数、
myProg.lpfnWndProcとコールバック関数の名前を同じにしますが、
それを2つのウィンドウで別々にすれば、自然と"hoge"でのイベントは
hogeCallへみたいになるんじゃないかと。
実はまだ複数のウィンドウのプログラムを作ったことが無かったので、
実験をすることも無くどうなるんだろうと質問してしまいました。
0252デフォルトの名無しさん
NGNG定石的にはMFCやATLがやってるように(それぞれ多少手段は違った気がするが)
ウィンドウと対応するC++なりのオブジェクトをつくってウィンドウ毎に処理を分ける。
0253159
NGNGiconインデクス取得して絵画まではいけますたが
引数で送ったpath以外のディレクトリを参照で選ばれた場合の
pathをうけとる方法がわかりませぬ。
どなたかご教授願います。
0254245
NGNGやっぱウィンドウが複数あったり、長編なプログラムは、
MFCとかで作るもんなんですかね。自分はMFCに挫折したくちでして。
SDKのみで作っている所で創プロはすごく参考になるのだけど、
やさしめのなので(それでも難しい)。
0255デフォルトの名無しさん
NGNGVBでいいのかな? 漏れの作ったのでよければ。
Private Declare Function SHChangeIconDialogA Lib "shell32" Alias "#62" (ByVal hWnd As Long, ByVal szFilename As String, ByVal Reserved As Long, lpIconIndex As Long) As Long
Private Declare Function SHChangeIconDialogW Lib "shell32" Alias "#62" (ByVal hWnd As Long, ByVal szFilename As Long, ByVal Reserved As Long, lpIconIndex As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Function ChangeIconDialog(ByVal hWnd As Long, strPath As String, Optional Iconidx As Long = 0) As Boolean
Const MAX_PATH As Long = 260
Dim strBuf As String * MAX_PATH, strRet(MAX_PATH) As Byte
Dim lPtr As Long, lRet As Long
strBuf = strPath & vbNullChar
If IsWinNT() Then ←OSがNTかどうか判断。自分で作る
lPtr = StrPtr(strBuf)
lRet = SHChangeIconDialogW(hWnd, lPtr, MAX_PATH, Iconidx)
CopyMemory strRet(0), ByVal lPtr, MAX_PATH
strBuf = CStr(strRet)
Else
lRet = SHChangeIconDialogA(hWnd, strBuf, MAX_PATH, Iconidx)
End If
If lRet Then
ChangeIconDialog = True
strPath = Left$(strBuf, InStr(strBuf, vbNullChar) - 1)
End If
End Function
呼ぶときは
Call ChangeIconDialog(Me.hWnd, パス, インデックス)
パス、インデックスに変更された値が戻ってくる。
0257デフォルトの名無しさん
NGNG0258デフォルトの名無しさん
NGNGWininetを使った汎用的なクラス(class Internet)を作りたいんだけど、
アプリケーション定義コールバック関数とInternetSetStatusCallbackへ渡すコールバック関数を使うと
コンパイル時に「warning C4312: '型キャスト' : 'DWORD' からより大きいサイズの 'Internet *' へ変換します。」
と出て、実行するとハンドルされていない例外が出て止まってしまうんだけど問題なく動かす為にはどうしたいいんだろう?
こんな感じ
//アプリケーション定義コールバック関数
virtual void callback( DWORD dwStatus, LPVOID lpStatusInfo );
//InternetSetStatusCallbackへ渡すコールバック関数
static void CALLBACK _inet_callback( HINTERNET hInternet, DWORD dwContext, DWORD dwStatus, LPVOID lpStatusInfo, DWORD dwStatusInfoSize)
{
( (Internet*)dwContext )->callback( dwStatus, lpStatusInfo );
}
0259245
NGNGとんでもございません。
>>247の書き方に失礼があったのならここでお詫び申し上げます。
>>257
使い方が分からないんです。猫のリソース・スクリプトも分かりません。
VBも挫折しました。ソースだけで作れるのでないと分からないです。
0260デフォルトの名無しさん
NGNGじゃぁ、一緒にC#勉強しませんか?
割と良い感じですよ。
MFCの嫌だったところが全てなくなってる。
0261デフォルトの名無しさん
NGNG何を悩む必要があるんだ?
hWnd1 = CreateWindow();
hWnd2 = CreateWindow();
WndProc()
{
if (hWnd == hWnd1) {
...
}
else if (hWnd == hWnd2) {
}
}
0262デフォルトの名無しさん
NGNG○戦う
○逃げる
0263デフォルトの名無しさん
NGNGC#からはじめればばっちりですよ。
0265245
NGNGC#ですか。どんな感じなのかいろいろ調べてみます。
ただ自分は、新しいのを覚えようとしないで、今ある知識で
工夫して何かを作ろうと考えてしまう所があって、
そのままSDKで作るかもしれませんが、その時はすいません。
>>261
グローバル変数はいけないという概念があって。WinMainは
スタートファイルだから、externとかしなくてもいいので
逆に使うことで困ることは無いと思うのですが。
0266デフォルトの名無しさん
NGNG×教授 ○教示
0267245
NGNGええ、全然慣れていません。
ゲームを作ろうと思ったのですが、コンソールアプリでは
表現しきれないので、グラフィックを使いたいと思って、
勉強を始めました。昔少しやったことはあったのですが。
正直うざいだけです。PeekMessage+Sleepのメインループで
グルグルがいいのですが、勉強するチャンスでもあるのでやってます。
C#はいいんですかね。文章を読んだだけで2人の方が進めてくれたので
まさに自分にぴったしのなのかもしれません。
0268デフォルトの名無しさん
NGNG(名)スル
(1)0 1 (ア)児童・生徒に知識・技能を与え、そこからさらに知識への興味を呼び起こすこと。
(イ)専門的な学問・技芸を教えること。
「国文学を―する」「書道―」
(2)0 大学などの高等教育機関において、専門の学問・技能を教え、また自らは研究に従事する人の職名。助教授・講師の上位。
いいんでない?
0269デフォルトの名無しさん
NGNGならstaticにすればいいじゃない。
変数名直で書くのがいやならクラスメンバにするとか。
形体はなんであれ、スタック以外の領域に、なんらかの形で
ハンドルを覚えておかないと分岐のさせようがないのはわかるでしょ?
0270245
NGNGそうですね。CheckHWNDみたいな関数があったとしても
もう片方の辺が無いから意味ないですし。
そういえば猫プロ(だっけ?)も始めに
char szClassNme[] = "ウィンドウクラス・ネーム" ;
みたいにWinMainの前にグローバル変数で書いてありますね。
0271デフォルトの名無しさん
NGNG0272245
NGNGそうだと思います。
ただ、長編のときはグローバル関数をあまり使わないで、
カプセル化(だっけ?)した方がよかったりするように、
極力使わないほうがいいのは分かっています。
ただ、逆に使わないと大変な所は、無理せず使うようにします。
0273デフォルトの名無しさん
NGNGまーそれでいいんじゃない。事情がわからんので適当だけど
普通は>>261よりは>>251のアプローチだと思うよ
0274デフォルトの名無しさん
NGNGウィンドウのタイトルバーの左側にあるアイコンを動的に設定する方法ってありますか?
今、
hIcon = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 0, 0, LR_CREATEDIBSECTION);
DrawIcon(GetDC(hWnd), 0, 0, hIcon);
などとやっていたんですが、
これはアイコンの設定ではなくて描画ですよね……。
WNDCLASS を毎回 RegisterClass() して対処しようかとも思ったのですが、
直前に RegisterClass() した時の WNDCLASS を取得する方法もわかりませんでした。
何か解決策はありませんか?
0275デフォルトの名無しさん
NGNGWM_SETICON
0276デフォルトの名無しさん
NGNGWM_GETICON?
0277デフォルトの名無しさん
NGNGただ、俺のやり方が悪いんだろうが、すぐAPIが恋しくなってDllImport使いまくってる。
0279デフォルトの名無しさん
NGNG.NET Frameworkのメモリ馬鹿食いはきにならない?酷すぎるんで結局W32APIに戻ってきたよ
0280デフォルトの名無しさん
NGNG実行中の重さは(GUI使わなければ)気になることはないね。
0281デフォルトの名無しさん
NGNG他の開発環境に戻りたくなくなってしまいますた。
0283デフォルトの名無しさん
NGNG元々でかくなるプログラムを書いてるんで、メモリ消費量は気にならない。
むしろ今は、未知の言語を触っているという楽しさがあるので、
使い慣れてきたら気になってくるかもしれんけどね。
0284デフォルトの名無しさん
NGNG実行は早いね。
メモリーが気になるのも同意。
マイクロソフトがこれを主流にする気みたいだから、
これで行っても大丈夫だろうとは思う。
0285デフォルトの名無しさん
NGNGコンパイルはできるけど、音がでない・・・OTZ
http://www.users.yun.co.jp/~studiowing/win32api/win-17.htm
ここの使ってるんですけど、何か注意する事とかありますか?
0286デフォルトの名無しさん
NGNGまあそれは良いとして、mciSendString の戻り値は確認したのか?
それなりのエラーコードが返ってるんじゃないか?
0287デフォルトの名無しさん
NGNG自前でやってるので大変です。
main関数を使ったときのargc, argvみたいに
簡単に取り出せるAPIはないですか?
0288デフォルトの名無しさん
NGNG0289デフォルトの名無しさん
NGNGおぉ。そういうのがあったのですか。
調べてみます。ありがとうございます。
0290デフォルトの名無しさん
NGNG0291デフォルトの名無しさん
NGNG0292デフォルトの名無しさん
NGNGうん。
>>291
(,,゚Д゚) ガンガレ!
029354
NGNGありがとん。返事が遅くなってスマソ。
>>58さんのGDI+で問題解決しました。
ttp://www.kumei.ne.jp/c_lang/sdk4/sdk_336.htm
0294デフォルトの名無しさん
NGNGMIDIファイルの位置が悪いとか……
実行ファイルのあるフォルダにMIDIをおいて、VSを使わずに直接実行してみても駄目?
0295232
NGNGビットマップを普通に表示するのは分かってきたのですが、
透過の仕方がわかりません。調べるとマスクとか書いてあるのですが分かりません。
以下のプログラムなら、どう発展させていけばいいのでしょうか。
http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=1060403548&res=61&fi=no
0296232
NGNGすいません。ShowBitmap関数のStretchDIBitsの最後の引数を
dwRopに変更してください。
後、実はその変更を行った後、たまたま人(前景)のほうの引数を
SRCANDにしたら透過できてしまいました。
SRCANDは「論理 AND 演算子を使って、コピー元の色とコピー先の色を
組み合わせます。」らしいのですが、なぜ透過できたのでしょうか。
0297デフォルトの名無しさん
NGNGttp://www.charlespetzold.com/
0298232
NGNGいろいろ調べていましたが分からないので、
1ピクセルずつ調べながら透過しない位置をGetPixelとかで
描画する方法でやってみます。お騒がせしました。
0299デフォルトの名無しさん
NGNGそこでなんで"たまたま"成功したかを追求すれば正解があるんだが。
0300232
NGNG自分はウィンドウズの基礎がなってないので難しいです。
一応>>298の方法で256色のはできました。
ただintのカウンタとforを使って普通にやっているので
表示するサイズが大きくなるとかなり遅そう。
0301デフォルトの名無しさん
NGNG1ピクセルずつやる、というのは妥当な方法だけど(マスク作るよりは楽)
それをやるならビットマップのメモリデバイスコンテキストに対してでは
なくDIBピクセル列に対して行うべきだね(DIBの操作は単純なメモリアク
セスなので、処理が圧倒的に早く正確)。
性能的には32ビットDIBで数百×数百ピクセルのビットマップを透過処理
しても、特に問題はない。
0302デフォルトの名無しさん
NGNG> ただintのカウンタとforを使って普通にやっているので
> 表示するサイズが大きくなるとかなり遅そう。
そういうもんです。
あとは、GetPixelみたいに1ピクセルごとに計算するのではなく、301さんが言うような方法で
メモリ上に展開することでループ計算や関数呼び出しのフィードバックを省略したり、
直接アセンブラをいじってMMXやSSEを呼び出し、数ピクセル分を一気に計算したりすることで
高速化を図ったりする。
0303デフォルトの名無しさん
NGNGDrawText(hDC, str, -1, &rect, DT_CALCRECT);
では、通常フォント文字の表示長方形領域を返してきます。
斜体フォント文字の表示長方形領域を正確に取得する方法をご存知の方、
教えていただけないでしょうか?
0304232
NGNG以下を>>295のプログラムのStretchDIBitsを消して
その位置に加えれば透過描画が出来ます。(8ビットのみ)
透過の位置はビットマップの左上と同じ色の位置です。
どこを直すといいでしょうか。
if(bmpInfo->bmiHeader.biBitCount == 8) //256色ビットマップ
{
int i ;
int updw = bmpInfo->bmiHeader.biHeight > 0 ? 1 : -1; //up,downどっちの方式か
int sizeX = bmpInfo->bmiHeader.biWidth; //サイズx
int sizeY = abs(bmpInfo->bmiHeader.biHeight); //サイズy
int dot = sizeY * sizeX; //ドット数
int p; //パレットの種類
int x, y; //拡大をしない表示する位置
int x2, y2; //拡大の分
int touka = updw > 0 ? lpBMP[dot - sizeX] : lpBMP[0]; //透過する色のパレットの位置
for(i = 0; i < dot; i++)
{
p = lpBMP[i];
if(touka == p)continue; //透過する位置
x = (spotX + i % sizeX) * bairituX;
y = (updw > 0 ? spotY + sizeY - i / sizeY - 1 : spotY + i / sizeY) * bairituY;
for(x2 = 0; x2 < bairituX; x2++)for(y2 = 0; y2 < bairituY; y2++)
SetPixelV(hdc, x + x2, y + y2,
RGB(bmpInfo->bmiColors[p].rgbRed, bmpInfo->bmiColors[p].rgbGreen,
bmpInfo->bmiColors[p].rgbBlue)); }}
0305デフォルトの名無しさん
NGNGGetTextExtentPoint32はどう?
0307デフォルトの名無しさん
NGNGhDCにフォントの指定はしてあるよね…?
0308306
NGNG指定してます。
OldFont = (HFONT)SelectObject(g_mem.hSzDC, hfont);
ワードパッドで斜体文字を表示して、選択で色を反転した時にわかる領域サイズと
同サイズが返ってきていると思われます。
Win32APIでは、斜体文字の表示範囲を取得するのは無理なのでは?
と思いはじめています。
0309デフォルトの名無しさん
NGNG私もやり方を知らない。
それらプラス tmOverhang が助けにならないのは知ってる。
GetCharABCWidths, GetCharWidth32, GetCharPlacement, GetGlyphOutline
あたりはためしてみた?
0310 ◆IGEMrmvKLI
NGNGInternetConnectをコールしているのですが、そのあと、アプリケーション終了時に
応答が帰ってこなくなることがあります。
マシンによって違い、アプリケーション終了後、正常終了して普通に終わるマシンと
アプリケーション終了後、正常終了して、タスクに応答なしで残りつづけるもの。
InternetConnect関数コール直後、デバッカによる停止で上記事象が発生するので、
そのあたりだとは思うのですが、OSによっての違いでもないみたいですし。
環境は、VB6.0SP5
Window2000 SP4
です。
応答が帰ってこない事象は、今のところ、Win2kSP3とSP4で確認しています。
逆に、通常に終わる場合は、WinXP・Win2kSP3・SP4・WinNTなどで確認しています。
原因について、思い当たるような節のあるかた、いらっしゃいましたらご教示よろしくお願いします。
0311デフォルトの名無しさん
NGNGで、結局Win2kSP3・SP4ではどういう挙動を示すんだ?
0312310 ◆IGEMrmvKLI
NGNGWin2kSP3・SP4の場合、タスクマネージャーに応答なしアプリケーションとして、
30秒程度?居残りつづける状態でした。
原因ですが、FTPサーバへのログインにAnonymousを使用していると、
同様の事象が発生するようです。
ほかのユーザを切りなおしてそのユーザでログインすると、その事象は解決しました。
どうも、ご迷惑をおかけしました。
0313デフォルトの名無しさん
NGNGShellExecuteEXでプロセスハンドルしか帰ってこないんです。
0314デフォルトの名無しさん
NGNGGetProcessId()でいいんじゃないの。
XP sp1 以降なら。
0315デフォルトの名無しさん
NGNGCreateProcessを使うとプロセスIDを取得出来るねぇ。
0316デフォルトの名無しさん
NGNGGetWindowThreadProcessIdというのもあるよ。参考までに。
0317313
NGNGXP sp1以降ということは、それ以前では感嘆には取れないんでしょうか?
>>315
データファイルを関連付けアプリで起動したいので、ShellExecute(EX)が
いいんです。
CreateProcessだとEXE直接起動オンリーですよね。FindExecutableで
さがせますけど、openのほかにprintとか他のverbもサポートしないと
いけないかも、なのでレジストリ直読みして環境変数置き換えて・・・・
マンドクセ
>>316
それだとウィンドウハンドルがわかんないといけないですけど、
プロセスハンドルからそのプロセスのウィンドウハンドルって取れます?
プロセスIDが分かっているときにウィンドウハンドルをとるなら
EnumWindowsとGetWindowThreadProcessIdで出来るんですが・・・
そのプロセスIDがわからんわけです。
0318デフォルトの名無しさん
NGNGttp://search.acty-net.ne.jp/mfc_search/archive/2001-1/msg03531.html
プロセスハンドルはシステム内で一意な値じゃないからそこから
プロセスIDを特定することは出来ないってことじゃないかな。
手間を惜しまないのなら、SetWindowsHookExかCreateRemoteThreadで
対象プロセスに自作のルーチンを進入させてGetCurrentProcessIdする手が
あるけど。
0319デフォルトの名無しさん
NGNGhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/ntqueryinformationprocess.asp
Windows2000 と WindowsXP (SP適用前) の場合限定で使えるんでない?
WindowsXP SP1 以降は GetProcessId() を使う方向で。
WindowsMe 以前は諦め…
0320デフォルトの名無しさん
NGNG9xでは構造体を直接読むという荒業が使えると思われ
どうせ9xはdisconなのだから将来の互換性の問題は気にする必要ないし
0321デフォルトの名無しさん
NGNG0322デフォルトの名無しさん
NGNG0323デフォルトの名無しさん
NGNGhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/taking_a_snapshot_and_viewing_processes.asp
0324デフォルトの名無しさん
NGNGdata_segとか使って全DLLで同じメモリ領域(HHOOKとか)を参照するようにしますよね?
でもそうすると、SetWindowsHookExを複数回呼ばれた場合に、
つまりSetWindowsHookExを含むDLLが複数のプロセスで呼び出された場合、
重複したフックが設定されてしまう可能性があります。
また、肝心のフック関数は処理結果を指定されたウィンドウハンドルに送るわけですが、
上記DLLを排他処理した場合、1つのウィンドウハンドルにしか送れなくなってしまいます。
これら問題を上手く解決する方法はないものでしょうか?
つまり、
SetWindowsHooExを呼び出す関数は、どのタイミングでどのプロセスから呼び出されても、
安全・確実に実行する事が出来き、かつその全ての呼び出し元が要求したウィンドウハンドルに、
全ての呼び出し元が開放を要求するまで、フック関数からのメッセージが確実に送信される、
というふうにしたいのです。
0325デフォルトの名無しさん
NGNG0326デフォルトの名無しさん
NGNGすみません。"フックハンドル 共有メモリ"でググってみましたが、見つかりませんでした。
共有メモリ領域を使わない方法とはどのようなものなのでしょうか?
0327デフォルトの名無しさん
NGNGにそれらしきレスがありますが、
CallNextHookExにNULLを渡すというのはソースが見つかりませんでした。
0328デフォルトの名無しさん
NGNGそれでも一応動くけど
CallNextHookExで正しいフックハンドルを渡さないと環境によってはシステム自体が著しく不調になる
0329324
NGNGHANDLE hMutex = NULL;
hMutex = ::CreateMutex( NULL, TRUE, SYSTEM_HOOK_MUTEX_NAME );
if ( hMutex == NULL ) {
// exception
}
if (::GetLastError() == ERROR_ALREADY_EXISTS) {
DWORDdwWaitResult;
dwWaitResult = ::WaitForSingleObject( hMutex, 1000 );
if (dwWaitResult != WAIT_OBJECT_0) {
// exception
}
}
g_hMouseHook = ::SetWindowsHookEx(
WH_MOUSE,
(HOOKPROC)g_MouseProc,
hinstDLL,
0
);
if (g_hMouseHook == NULL) {
// exception
}
::ReleaseMutex( hMutex );
0330デフォルトの名無しさん
NGNG0331デフォルトの名無しさん
NGNG0332デフォルトの名無しさん
NGNG0333デフォルトの名無しさん
NGNG0334デフォルトの名無しさん
NGNG0335デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています