[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 03/27 14:57 / Filesize : 277 KB / Number-of Response : 972
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

くだすれDelphi(超初心者用)その51



1 名前:デフォルトの名無しさん mailto:sage [2009/12/01(火) 20:41:37 ]
Delphi(デルファイ)について、他のスレッドでは書き込めない超低レベル、
もしくは質問者自身何が何だか分からない質問を
勇気を持って書き込むスレッドです。
Delphi使いが優しくコメントを返しますが
お礼はDelphiの布教と初心者の救済をお願いします。

<前スレ>
くだすれDelphi(超初心者用)その50
pc12.2ch.net/test/read.cgi/tech/1246340765/

<過去スレ>
DelWiki避難所(Delphi 関連の過去スレッド)
delwiki.info/?%E3%83%AA%E3%83%B3%E3%82%AF%2F%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%2FDelphi%20%E9%96%A2%E9%80%A3%E3%81%AE%E9%81%8E%E5%8E%BB%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89

655 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 06:47:59 ]
>>653
レスありがとうございます。
その描画色はなん色か時間によって変わっていって黒は使われていないんです。
描画されている文字列を取得すると正しく取得できるし、WinSightで見てもハンドルは
間違ってはいないので、デバイスコンテキストも間違ってはいないと思うのですが。


656 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 07:35:18 ]
>>654
>特に後者は、確実に refCnt いじってメモリーリークしているので危険。

w: WideString;
s: String;

w := '幹事';
s := AnsiString(Pointer(w));

がリークするの?
FastMM4は沈黙してるけど。


657 名前:654 mailto:sage [2010/05/13(木) 12:26:30 ]
Windows では、WideString は、OLE 文字列や BSTR 互換なので、
AnsiSting とは、メモリ管理方法が異なる。
WideString は、SysAllocStringLen などで
領域確保しているので FastMM4 の管理外。

WideString のオフセット -4 には、長さに相当するバイト数が
格納されていて、それ以外はしらん。
しかし、AnsiString を代入するときは参照カウントが格納されている
オフセット -8 の refCnt フィールドを調べたり、いじったりする。


658 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 12:39:38 ]
WideString (BSTR) は参照カウンタ管理されていないので、ストリングのコピーが複製になるため「遅い」
という問題を回避するために導入されたのが参照カウンタ付き UnicodeString なわけなので

WideString 側には refCnt なんてフィールドはありませんよ。
UnicodeString と混ざってしまっているかな?

659 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 13:47:46 ]
なんか疑問だな バイナリを入れるなら byte の配列を用意したほうが自然
Bytes: array of byte; で、WStr := WideString(Pointer(Bytes)); でどうなのか

660 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 14:14:50 ]
WStr := WideString(Pointer(Bytes))
だと、Bytes配列はヌル終端してる必要ある?


661 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 14:22:08 ]
>>659
バイト配列の話なんて誰もしてないから

662 名前:646 mailto:sage [2010/05/13(木) 16:31:53 ]
>>647
どういう点がセンスいいのか言ってもらわないとw 怖いもの知らずっていう意味ですか

>>651 ご意見感謝します
バージョンは6のPersonalです
作成中のアプリのコードを現代のバージョンに持って行くことはまず考えられません
しかし気持ちとしては、現代のバージョンにも転用可能なコードを書きたいと思いますし、
理解できていない・正体のハッキリしないモノ=ポインタ絡みの操作や原理不明のキャスト
も出来れば使用したくない、というのが本音です キャスト成功で手放しで喜んでいるわけではないです
なお、最近のバージョンではTEncodingとかRawByteStringとか、良さそうなものがあるようですね

>乗り換えることがあるなら、string型はすでに仕様が2回ほど変わった過去があるので
すごく承知してます
Stringでなく、AnsiStringと記述してるのは上記のような気持ちからです(あまり意味有りませんが)
自分が調べた限りではこんな感じですが、だいたい合ってますよね
■AnsiStringの系譜  D1:ShortString → D2:AnsiString → D2009:AnsiString(コードページ指定可能)
■Stringのデフォルト D1:ShortString → D2:AnsiString → D2009:UnicodeString
※ UnicodeString=AnsiString(1200)
※ D2:AnsiString、D2009:AnsiString/コードページ指定なし のコードページはシステムのロケールに依存
※ D2009:AnsiString(コードページ指定)では変数ごとに複数のコードページを保持できる
※ RawByteString=AnsiString(65535) コードページの変換をしない

やりたいことは、バイナリファイルを読み込み、特定条件の文字列や数値を検索して抜き出し、
変更を加え再構成して新たなファイルを作成、という操作です ゲーム改造みたいな感じでしょうか
いったんバラバラにしたデータを再構成する、つまり切ったりつなげたりをスマートに行う方法が
分からず、こんなことで悩むなら足し算引き算自由の文字列を使うべきかと結論付けました
配列だと、array[0..n] of Charまたはパック文字列型、StrPCopy、StrPas、Move
このあたりを使用するんでしょうか?

663 名前:646 mailto:sage [2010/05/13(木) 16:34:38 ]
>>654 ありがとうございます
WStr:=WideString(PWideChar(Pointer(Bytes))) ではヌル除去、
WStr:=WideString(Pointer(Bytes)) だとヌル保存を確認しました
少しだけナルホド、です

でも高度に技術的なお話はちょっと分からないです…
確かにSystem.pasにはそういうのがありますね、としか…
procedure _WStrFromPWChar(var Dest: WideString; Source: PWideChar);
procedure _WStrAsg(var Dest: WideString; const Source: WideString);
procedure _LStrAsg(var dest; const source);
procedure _WStrFromLStr(var Dest: WideString; const Source: AnsiString);
procedure _LStrFromWStr(var Dest: AnsiString; const Source: WideString);


みなさんのご意見をまとめると、「これらのキャストはすべて危険、未来も無いからやめとけ」
ってことですね?
しかし、配列優位とも思えませんので、文字列型を使いつつキャストもしない、という方針で
やってみようかと思います


>>659
えーと、私もそう考えて、というかByte型という名前に惹かれて、当初はTByteDynArrayでした
あと、1byte=Byte型配列の要素1個 というのも気持ち良い感じがしたんですが…
やはりバラバラにして再構成というのが配列の用法と合わないと思いました
>>661
いえ、話の発端の私がしておりますので…



664 名前:654 mailto:sage [2010/05/13(木) 16:44:54 ]
>660
PWideChar じゃないから危険だって。

PWideChar -> WideString はヌル終端までを変換するけど、
Pointer -> WideString はただの型キャスト。

PChar/PAnsiChar/PWideChar -> AnsiString/WideString/UnicodeString
=> ヌル終端までを変換

AnsiString/WideString/UnicodeString -> PChar/PAnsiChar/PWideChar
=> ヌル終端を保証

PAnsiChar/PWideChar/AnsiString/WideString -> Pointer
=> 型キャスト

Pointer -> PAnsiChar/PWideChar/AnsiString/WideString
=> 型キャスト


665 名前:654 mailto:sage [2010/05/13(木) 16:52:06 ]
ついで。
Dynamic Array -> Pointer
=> 型キャスト

Pointer -> Dynamic Array
=> 型キャスト


666 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 21:33:15 ]
>「これらのキャストはすべて危険、未来も無いからやめとけ」

んなこたない。
生ポインタをC文字列とみなしてDelphiの文字列に変換する機能は
Win32APIを叩く際の根幹的な機能だからそんな簡単に仕様変更なんてあるわけがない。
いくらなんでも脅かされすぎ。

667 名前:646 mailto:sage [2010/05/14(金) 02:20:53 ]
あれ、今までのレスをよく見直すと、
WStr:=WideString(Pointer(Bytes))
は危険な可能性有りだけど、
WStr:=WideString(PWideChar(Pointer(Bytes)))
は問題無いと言う見解ですかね?

>>666
仕様変更は無いだろうというご意見も覚えておきます
どちらにせよ、もうキャストはしないと決めました
「キャスト」なる仕組みは完全に明らかである、という状況ではない以上、
使うべきではないと思いました

668 名前:646 mailto:sage [2010/05/14(金) 02:23:12 ]
こんな感じの関数で十分でした
これなら不明な点はありませんから問題無いですよね

function BytesToUTF16LE(Bytes: AnsiString):WideString;
var
  I:    Integer;
  WOrd: Integer;
begin
  Result:='';
  for I:=1 to Length(Bytes) div 2 do begin
    WOrd:=(Ord(Bytes[I*2]) shl 8)+Ord(Bytes[I*2-1]);
    if WOrd=0 then break;           // ヌルを含めるならこの行を外す ※ヌルは複数組の可能性もあり
    Result:=Result+WideChar(WOrd);
  end;
end;


function UTF16LEToBytes(WStr: WideString):String;
var
  I: Integer;
begin
  Result:='';
  for I:=1 to Length(WStr) do begin
    Result:=Result+Char(Lo(Ord(WStr[I])))+        // and $00FF
                   Char(Hi(Ord(WStr[I])));        // Shr 8
  end;
end;

キャスト方法のアドバイスをくれた方、ご意見下さった方、ありがとうございました
大変勉強になりました

669 名前:デフォルトの名無しさん mailto:sage [2010/05/14(金) 03:12:16 ]
>>666
今までに変更があったという事実は無視なの?

670 名前:デフォルトの名無しさん mailto:sage [2010/05/14(金) 04:43:03 ]
コーディングスタイルは人それぞれだね
1行だけのforならbeginもendも不要なのに

671 名前:デフォルトの名無しさん mailto:sage [2010/05/14(金) 04:46:14 ]
エンバグの元なのに?

672 名前:デフォルトの名無しさん mailto:sage [2010/05/14(金) 06:40:31 ]
既に決着済みではあるけど一言だけ。

>>667
>「キャスト」なる仕組みは完全に明らかである、という状況ではない以上、
明らかに間違った使い方は示されたけど
Delphiの仕様の抜け道を使ったような未定義のやり方はないよ。
少なくともそんな指摘はまったく出ていないように思うが。

曖昧論やらべき論は出てきたが。

673 名前:652 mailto:sage [2010/05/14(金) 08:14:15 ]
GetTextColorについて質問をしたものです。
あれから色々試していたのですが、例えば赤で描かれたテキストがあって、
その色を取得しようと、GetDCPenColor、GetDCBrushColor、GetBKColorとか
やってみたのですが、赤の値が取れませんでした。
何か他にやり方ってあるのでしょうか。
それとも、アキラメロンなのでしょうか。




674 名前:デフォルトの名無しさん mailto:sage [2010/05/14(金) 10:29:38 ]
>>673
座標を取ってGetPixelしてみるとかはどう?

675 名前:デフォルトの名無しさん [2010/05/14(金) 21:57:57 ]
描かれてしまったものは単なる絵だから。
描いたときのペンやブラシやテキストカラーの設定が現在も残ってると期待するのは無理

676 名前:652 mailto:sage [2010/05/14(金) 23:43:02 ]
>>674
ありがとうございました。
GetPixelで何とか出来ました。

>>675
そういうことなんですね。
納得しました。
ありがとうございました。

677 名前:デフォルトの名無しさん mailto:sage [2010/05/15(土) 00:08:51 ]
Form1の他にForm2を作ってメニューからForm2の表示、非表示させてるんだけど、
Form2を表示中にメインのForm1を最小化させると一緒に画面から消えちゃうの何とかならん?

678 名前:デフォルトの名無しさん [2010/05/15(土) 15:35:35 ]
今デルヒで一番安く手に入る環境(違法じゃないの、新品の)でお願いします?

679 名前:デフォルトの名無しさん [2010/05/15(土) 16:10:05 ]
>>678
kaidoku.ocn.ne.jp/shopping/nv/member/item/detail/_/item_id/1090901509/

コンポーネントを一緒に買う気があるなら
www.componentsource.co.jp/products/delphi-2010-j/prices.html

680 名前:デフォルトの名無しさん [2010/05/15(土) 16:13:24 ]
あ、直販の方が安いのか
www.embarcadero.com/jp/radoffer

681 名前:デフォルトの名無しさん mailto:sage [2010/05/15(土) 22:29:59 ]
頼む 日本語で

682 名前:デフォルトの名無しさん [2010/05/18(火) 11:26:08 ]
Delphi7ですけどIDE終了時AVなるのでコード変更してみました
これでいいでしょうか
_LStrClr関連で調べていたら_LStrFromPWCharLenのBuffersが悪さしてるみたいので
procedure _LStrFromPWCharLen(var Dest: AnsiString; Source: PWideChar; Length: Integer);
var
  DestLen: Integer;
begin
  if Length <= 0 then
  begin
    _LStrClr(Dest);
    Exit;
  end;
  DestLen := CharFromWChar(nil, 0, Source, Length);
  SetLength(Dest, DestLen);
  if DestLen > 0 then
  begin
    CharFromWChar(Pointer(Dest), DestLen, Source, Length);
  end
  else
    _LStrClr(Dest);
end;


683 名前:デフォルトの名無しさん [2010/05/18(火) 12:02:46 ]
こっちも変えてみました
procedure _WStrFromPCharLen(var Dest: WideString; Source: PAnsiChar; Length: Integer);
var
  DestLen: Integer;
begin
  if Length <= 0 then
  begin
    _WStrClr(Dest);
    Exit;
  end;
  DestLen := WCharFromChar(nil, 0, Source, Length);
  SetLength(Dest, DestLen);
  if DestLen > 0 then
  begin
    WCharFromChar(Pointer(Dest), DestLen, Source, Length);
  end
  else
    _WStrClr(Dest);
end;




684 名前:デフォルトの名無しさん mailto:sage [2010/05/18(火) 22:30:32 ]
カード占いをするソフトを作りたいと思っています。

(1)カードの使用枚数と配置を決める
(2)カードを配置して裏返し、表示させる。

(1)でカードの位置を、マウスでクリックした位置に決めて
カードの裏向きの画像ファイルを表示させたい
のですが、どうすればいいでしょうか。




685 名前:デフォルトの名無しさん mailto:sage [2010/05/18(火) 23:04:57 ]
ActiveXのWindowsMediaPlayerコンポーネントで、
動画再生時にビデオの明るさを変更する方法はありますか?

WindowsMediaPlayerの「拡張設定」の「ビデオ設定」にある「明るさ」を変更できる方法があればいいのですが。

686 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 00:51:54 ]
>>684
その通りにやればいいだけじゃ?
どこで詰まったのかもっと具体的に言わないと答えようがないだろ
一から手取り足取り教えてもらいたいなら金払ってサポートしてもらえ

687 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 03:56:58 ]
>もしくは質問者自身何が何だか分からない質問を
>勇気を持って書き込むスレッドです。
>Delphi使いが優しくコメントを返しますが

トランプの裏向きの画像は手に入れているとして。

フォームに CardImage という名前の TImage を作成。
Picture プロパティに画像を設定。
Visible プロパティを False に。

*クリックしたら
From の OnMouseDown イベントメソッドを作成

*位置を決めて
引数の X と Y を使う。

* 画像ファイルを表示
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
I : TImage;
begin
I := TImage.Create(self);
I.Parent := self;
I.Picture.Assign(Image1.Picture);
I.Width := Image1.Width;
I.Height:= Image1.Height;
I.Left := X;
I.Top := Y;
end;


688 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 12:06:14 ]
マルチスレッドのデバッグってどうすればいいでしょうか?
1つのスレッドを動的に複数Createして同時に実行した時に、ブレークポイントで止めていると
Delphiが固まってしまいます。
Del7です。
よろしくお願いします。

689 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 15:55:47 ]
>ブレークポイントで止めていると Delphiが固まってしまいます。
D7 が現役の頃にはそんな経験無いですけどね。

>Del7です
OS は? CPU は?

Vista/Win7 だとあきらめるしかないかも。

690 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 16:35:03 ]
起動中のアプリケーションでコマンドラインを受け取るにはどうすればいいのでしょうか?

a.exe -hoge -piyo
が何度か呼び出される感じ(引数は変わる)なのですが・・・
多重起動は禁止にしてます。

691 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 16:55:10 ]
すでに起動中のアプリケーションに、後から起動された(同一)アプリケーションのコマンドラインオプションを
渡すのかな?

Windows はマルチタスク/マルチインスタンスサポートの OS なので、別々に起動されたアプリケーションは
別々のインスタンスとして管理されます。何らかのアプリケーション間通信をおこなう必要があります。

擬似コードとしては

program A;

begin
if 俺は起動中かな then
begin
  起動中のインスタンスにコマンドラインを渡す( paramstr(1), paramstr(2)...)
end
else
通常実行開始
end;

後から起動されたアプリケーション A2 から、すでに起動しているアプリケーション A1 にデータを送るには、
sendmessage がつかえますが、メッセージを受信するためのウィンドウが必要(非表示でよし)なので
純粋なコマンドラインツールだと余計な手間がかかるでしょう。

692 名前:688 mailto:sage [2010/05/19(水) 17:05:30 ]
>>689
レスありがとうございます。
説明不足でした。
ブレークポイントで止まってるだけなら何ともないのですが、ステップ実行を何行かすると
フリーズしてPCのリセットボタンを押さないといけなくなります。
マルチスレッドが1つだけの時は、正常です。
ヘルプを見るとマルチスレッドのデバッグの項目はあるのですが、イマイチよく分からないです。


693 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 17:14:22 ]
>>292
XP+Turbo(2005)のわたしも同じ状況に見舞われてます。
以前わたしも、ここか雑談スレで相談しましたが、解決方法はわかりませんでした。

一応、めちゃくちゃ反応は鈍いですが、操作は可能です(時間的には、リセットで再起動の方が早いと思いますが)。
こちらでは、頻度は低いですが、マルチスレッドというか、シングルスレッドでも起こりますので、
スレッドをデバッグした時になるのだと思います(といっても、メインスレッドは別だから、結局はマルチスレッドなのだろうけど)。

おそらくデバッガーの問題かと。こちらでは、なるべくブレークポイントは使用しないという消極的な回避策で対処してます。



694 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 17:28:09 ]
>>691
ですです。
だいたいおんなじことを考えていたのですが、
>  起動中のインスタンスにコマンドラインを渡す( paramstr(1), paramstr(2)...)
ここがわかりませんでした。
後出しですみません。

作ってるアプリはGUIアプリです。

695 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 17:32:15 ]
>>694
あと、コマンドラインを渡したあと、どうやって受け取るのかもわからなかったです。。。

696 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 18:54:34 ]
>>687
やっぱりああやって書くとレス付きやすいですねw
あざーすww

697 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 18:57:28 ]
>>694
SendMessageが使えるって書いてあるじゃん
よく読めよ

698 名前:684 mailto:sage [2010/05/19(水) 21:08:27 ]
>>686,687
ありがとうございます。
やってみます。


699 名前:デフォルトの名無しさん mailto:sage [2010/05/19(水) 22:25:41 ]
>>696はいかにもゆとり

700 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 00:51:52 ]
マルチスレッドのデバッグっていくつか前に書いてなかったか。
俺も参考にさせてもらった。
今は忘れた。w

701 名前:これかな? mailto:sage [2010/05/20(木) 01:10:29 ]
178 名前:デフォルトの名無しさん[sage] 投稿日:2009/08/12(水) 10:30:13
OutputDebugString使いまくる

179 名前:デフォルトの名無しさん[sage] 投稿日:2009/08/12(水) 10:38:37
>>175
現状では各スレッドに固有の番号を持たせて(多少面倒だがThreadId等でもいい)、
条件付きブレークでその番号をセットすれば任意のスレッドだけブレークさせることが可能

180 名前:175[sage] 投稿日:2009/08/12(水) 13:48:14
>>178-179、レスありがとうございました。
Delphiがフリーズせずにデバッグできるようになりました。
勉強になりました。

702 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 05:00:38 ]
>あと、コマンドラインを渡したあと、どうやって受け取るのかもわからなかったです。。。

Google で以下のキーワードで検索。
sendmessage プロセス間通信 Delphi

Delphi では無いが yokohama.cool.ne.jp/chokuto/advanced/copydata.html はよくまとまっていてよろしい。

それと、目的は複数のプロセスが同じデータを参照すること。と見なせば、
共通のファイルやレジストリにコマンドラインを記録し、
通常起動しているプロセス側がポーリング(定期的に見に行く)する。
という手法も使えます。


703 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 05:11:24 ]
XP の頃、 MS-IME とデバッガの相性の問題があったはず。

ttp://www2.atwiki.jp/lunatips/pages/10.html

ttp://d.hatena.ne.jp/rabbithutch/20050211

試してみてくださいな



704 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 10:38:55 ]
if文の書き方で

if A=B then・・・・・・・・@
if C=D then・・・・・・・・・T
E:=F;
else if A<B then・・・・A
E:=G
else A>B then・・・・・・B
E:=H;

@ABを条件分岐のグループで@の時だけ、入れ子のifを実行するつもりなんですが、
どうも、DelphiはTとABをグループと見るみたいで 「E:=F;」 の「;」がだめってコンパイルエラーが
出ます。
begin〜endで囲んでいけば欲しい動きにはなるのですが、単純な構文なので無意味に行数を増やしたくないのですが、
ifの中にifを入れる時はbegin〜endで囲むのがルールなんでしょうか?

705 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 10:40:13 ]
インデントしたつもりがされなかったです。
これでどうだ

   if regCurrent=Current then
    if lblCurrent.Font.Color=clWhite then
     lblCurrent.Font.Color:=clYellow;
   else if regCurrent<Current then
    lblCurrent.Font.Color:=clRed
   else if regCurrent>Current then
    lblCurrent.Font.Color:=clLime;


706 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 11:03:39 ]
素直に begin end でくくれ。


707 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 11:11:39 ]
>>705
余計な話ですが、最後のelse、意味通りのインデントになってる?

708 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 11:16:11 ]
; が文の終わりを表す C 系の規則と
; が文の区切りを表す Algol/Pascal の規則の差なのですが、
そういう物だと納得して先に進む方が賢いです。

それとネストした if/else 構造は、どの言語でも分かりにくい表記をすることができる物で、
C 言語でも

if (A)
 if (B)
  process1();
else
 process2(); // A に対する else ? B に対する else ?

さらに変なインデントがついていたりすると、予想外のミスを呼び込むかもしれません。

20年くらい前の構造化言語の導入時には、else がどの if に対応するべきかが議論対象になり、
else にオプションをつけて対応する if を(必要な時は)明示指定したらどうか?という試験的な言語も存在しました。
現在は、単純に直近の if を対象にする。という規則が一般的です。
数行を惜しんで分かりづらくするよりは、begin - end を明示的に入れてあげた方がコードの保守性という見地からも
得策でしょう。
なお、「else は直近の if に対応する」というルールを使って空の else 節を挿入する。というトリックもあり得ます。

 if A=B then
  if C=D then
   E:=F
  else
 else if A<B then
  E:=G
 else if A>B then
  E:=H;

これが「美しい」「わかりやすい」かどうかは、また別の話ですね。

709 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 11:27:41 ]
皆さん、ありがとうございます。
基本的には begin〜end は保守性の面から入れるのですが
今回の質問のような単純で短い構文で、狙った動きにならないので
びっくりしたのと納得できなかったので質問しました。

>直近のifに対応する
こんな規則で動いていたんですね。
納得しました。

ありがとうございました。

710 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 11:47:07 ]
綺麗さ、かつ Pascal の特性を活用するなら、入れ子関数を作って、
関数名をコメントがいらないくらい分かりやすいものにしてしまう。
というのも実用性の高い手法です。

新しめの処理系なら、日本語関数名も使えますしね。

  procedure SetFontColor(originalColor, modifiedColor: TColor)
  begin
   if lblCurrent.Font.Color = originalColor then
   lblCurrent.Font.Color:=modifiedColor;
  end;

 if regCurrent=Current then
  SetFontColor(clWhite, clYellow)
 else if regCurrent<Current then
  lblCurrent.Font.Color:=clRed
 else if regCurrent>Current then
  lblCurrent.Font.Color:=clLime;



711 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 12:29:21 ]
なるほど。
ちょっとの手間でスマートですね。
まだ、この辺の手間をかけた方が後々いいのか、どうかの判断が
出来ないレベルなので参考にさせてもらいます。

712 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 17:43:30 ]
>>697,702
ありがとうございます。
ググりつつコピペしつつ改変しながら
eggrice.no.land.to/up/src/tohoh0403.txt
と言うふうに書いてみたんですが、
二度目に起動したときに前のウィンドウがアクティブになるだけで
メッセージの処理は行われませんでした。

winexpでメッセージ監視してみたら
TMainFormじゃなくてTApplicationにメッセージが飛んでいたので
これが問題かな?と思ってFindWindowでハンドル取得してみてもうまくいきませんでした。

どこか間違えているでしょうか?

713 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 12:56:44 ]
>>704 これあきらかにおかしいじゃん

if A=B then if C=D then E:=F; ここまで1行とコンパイラは理解するから次の else if が文法上間違い



714 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 14:33:18 ]
質問が紛らわしくてすんません。
@ABの条件分岐のつもりで、@の時にTを実行する意図なのですが
「F;」の「;」を取ると
TABがグループと認識して@の入れ子と処理されてしまいます。
Tは単独のif文にする意図で「;」を付けるとコンパイルエラーになるので
「何で?」と言う意味でした。

715 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 15:00:07 ]
だいじょうぶ。意図を理解している人もいるよ。


716 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 17:01:10 ]
自作アプリをプログラムから最小化してタスクバーに入れるにはどうすればいいですか。
WindwStataだとタスクバーの上に表示されてしまいます。

717 名前:716 mailto:sage [2010/05/21(金) 17:07:39 ]
出来ました。

718 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 07:52:47 ]
Continueってバグを起こしますか?
for i:=0 to max do
begin
if hoge then
begin
continue;
end;
end;

デバッグしているとi = maxの時にcontinueが実行されるとループが進んでしまうのですが・・・

719 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 12:26:05 ]
あなたの頭がバグを起こしているだけです

720 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 12:32:28 ]
デバッグしろ

721 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 14:16:18 ]
max-1が正しかったという罠

722 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 18:43:28 ]
マルチスレッドが存在するかしていないかって、分かる関数とかってあります?
Createした時に覚えておいて、解放する時はメインの方から明示的にFreeするしかないんでしょうか?

723 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 19:01:08 ]
>718
ブロック内で、変数Iを使っていないので、最適化されて減少カウンタとして利用されている予感。



724 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 19:57:31 ]
>722
スレッド終了時に自分で自分を解放

>718
>723のいうとおりだと思う。コンパイルオプションで最適化を外すとデバッグしやすくなる。

725 名前:デフォルトの名無しさん mailto:sage [2010/05/25(火) 12:47:56 ]
最後に判定しに行くだけだろ?
Cで書けばfor(i=0;i<=max;i++)なんだからmaxの次に判定があるのは当たり前
アホか

726 名前:デフォルトの名無しさん mailto:sage [2010/05/25(火) 17:11:33 ]
>>722
一応IsMultiThreadってグローバル変数が存在してるけど。ソースみりゃわかるけど、
直接Win32のCreateThreadとか呼んだら駄目ぽだけど。BeginThreadかTThreadクラスだけを
使ってる場合だけオk。

727 名前:デフォルトの名無しさん mailto:sage [2010/05/25(火) 17:14:10 ]
ああでも、ダメポそうだな。ごめん。

728 名前:デフォルトの名無しさん mailto:sage [2010/05/26(水) 00:04:05 ]
>>722
WaitForと言うのがあるらしい。
使い方は分からない。

お知恵をお借りしたいのですが。
今、複数起動が前提のアプリを作っているのですが、
一斉に最小化や復元をしたいと思って共有メモリを
使うところまでは出来たのですが、例えば一斉に最小化の場合は
メニューをクリックされたソフトで共有メモリに「1」を入れる。

他のソフトはその「1」がたったかどうかで最小化すればいいのですが、
お知恵を借りたいのは「1」をどのタイミングで「0」にすればいいかです。
全部が最小化されたかどうかを知るにはどうすればいいかって事です。

考えたのは複数起動した数を共有メモリに記録しておいて、メニューをクリック
されたら「1」ではなく、起動数を入れて(例えば「10」)で最小化したら 
-1 していくと言うやり方です。

他にもっとスマートなやり方があれば教えて下さい。 


729 名前:デフォルトの名無しさん mailto:sage [2010/05/26(水) 00:46:32 ]
HWND_BROADCAST

730 名前:デフォルトの名無しさん mailto:sage [2010/05/26(水) 13:33:42 ]
e?

731 名前:728 mailto:sage [2010/05/26(水) 14:07:31 ]
レス、ありがとうございます。

>HWND_BROADCAST
ググってみます

732 名前:728 mailto:sage [2010/05/26(水) 18:53:43 ]
ググったけど、よう分からんかったです。
SendMessageやPostMessageでHWND_BROADCASTを送ると
関係ないアプリまで最小化や終了をさせてしまうことになりませんか?


733 名前:デフォルトの名無しさん mailto:sage [2010/05/26(水) 19:28:16 ]
RegisterWindowMessageって知ってるか?



734 名前:デフォルトの名無しさん mailto:sage [2010/05/26(水) 21:25:07 ]
>>733
> RegisterWindowMessageって知ってるか?
おぉ、ありがとうございます。
ググって来ました。
確認させて下さい。

例えば、WM_APP+100は一斉に最小化、WM_APP+101は一斉に終了みたいに決めておいて
アプリ起動時に
RegisterWindowMessage(WM_APP+100);
とかやって登録して
一斉に最小化させたい時は SendMessage(HWND_BROADCAST , WM_APP+100 , 0 , 0);
とやればいいって事ですか?

受け取りは WndProc(ググった先で出てきたので、よく分かってないです。)を使って送られて来た
メッセージによって処理する

こんな感じで良いでしょうか?

735 名前:デフォルトの名無しさん mailto:sage [2010/05/26(水) 21:42:18 ]
RegisterWindowMessageの引数は文字列

RegisterWindowMessage(自分だけの文字列)

SendMessage(HWND_BROADCAST, RegisterWindowMessageの戻り値, ここ, とここは自分で決めて振り分ける);

736 名前:728 mailto:sage [2010/05/27(木) 00:41:49 ]
>>735
思い通りの動きが出来ました。(;゚∀゚)=3
ありがとうございました。

737 名前:デフォルトの名無しさん mailto:sage [2010/05/28(金) 23:12:46 ]
var
Form1: TForm1;
days:double;
procedure TForm1.Button1Click(Sender: TObject);
begin
days :=VarToDateTime('28/5/2010') - VarToDateTime('27/4/2010');
showmessage(FloatTostr(days));
end;

これは2010年4月27日と2010年5月28日の日数の差として「31」が表示されます
こんな感じで2010年4月27日から31日経つと「2010年5月28日」のような処理をしたいのですが、どうすればよいのでしょうか?

要はTDateTime 型から日付を求めたいのです


738 名前:737 mailto:sage [2010/05/29(土) 00:01:44 ]
ごめんなさい自己解決しました

739 名前:デフォルトの名無しさん mailto:sage [2010/05/29(土) 20:46:03 ]
>>712ですが、
結局TMainFormというインスタンス名が他のアプリケーションで使われていたようでうまくいかなかったので
メッセージ受信専用ウィンドウを利用する方法を使いました。

メッセージ用ウィンドウプロシージャは
特定のメッセージがきたときだけMainFormにDispatchするようにして
あとはDefWindowProcに渡すようにしたのですが、
処理としてはあっているのでしょうか?
初めはディスパッチのみでDefWindowsProcを呼び出さずにしていたら
終了時にエラーがでました。

740 名前:デフォルトの名無しさん mailto:sage [2010/05/29(土) 22:19:45 ]
名前変えればいいだけじゃ・・・

741 名前:デフォルトの名無しさん mailto:sage [2010/06/06(日) 20:53:51 ]
下のソースをJavaに移植したいのですが、内容が理解できなくて困っています。
下から7行ほど前からが理解できないので・・・、別言語に書き換えて教えて頂けないでしょうか?
java, c, perl , php, vb, javascript 辺りの書き方であれば理解できます。

function EncodeB32(s: String): String;
const
B32Char: array[0..31] of Char =
('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V');
var
i: Integer;
len: Integer;
begin
if s = '' then begin
Result :='';
Exit;
end;
len := (Length(s) * 8 - 1) div 5 + 1;
s := s + StringOfChar(#0, (len * 5 - 1) div 8 + 1 - length(s));
SetLength(Result, len);
for i:=0 to len - 1 do
Result[i + 1] := B32Char[(MakeWord(Byte(s[(i * 5) div 8 + 1]), Byte(s[(i * 5) div 8 + 2]))
shr ((i * 5) mod 8)) and 31];
end;

742 名前:E- ? mailto:sage [2010/06/06(日) 21:31:21 ]
BASE32 だから、検索すれば仕様書があるはず。仕様書から作ったほうが早いよ。私はCで作った。
function EncodeB32(s: String): String;
const
    B32Char: array[0..31] of Char =
        ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
        'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V');
var
    i: Integer;
    len: Integer;
begin
    if s = '' then begin
        Result :='';
        Exit;
    end;
    len := (Length(s) * 8 - 1) div 5 + 1;
    s := s + StringOfChar(#0, (len * 5 - 1) div 8 + 1 - length(s));
    SetLength(Result, len);
    for i:=0 to len - 1 do
        Result[i + 1] := B32Char[(MakeWord(Byte(s[(i * 5) div 8 + 1]),
                                   Byte(s[(i * 5) div 8 + 2])
                                  ) shr  ((i * 5) mod 8)
                                 ) and 31];
end;

743 名前:デフォルトの名無しさん mailto:sage [2010/06/06(日) 21:38:01 ]
Javaならライブラリあるだろうに。



744 名前:デフォルトの名無しさん [2010/06/06(日) 21:39:03 ]
これで事足りないというなら出直して来るんだ
つttp://www.google.co.jp/codesearch?hl=ja&q=base32+lang:java


745 名前:デフォルトの名無しさん mailto:sage [2010/06/06(日) 23:49:13 ]
あれ、関数名はBase32だったので、そう思って組んでみたんですが、結果が違ったので・・・

1. そのソースコードが使われいるexe
$ exec "1c68ee574965514ec9c27a57972719ea"
4NDXFOSLFKFHMTQT2K6LSOGPK

2. Base32エンコード
$ echo "1c68ee574965514ec9c27a57972719ea" | java Base32encode
S0QSUB595BKSK4B0QRLEPJ43A7

>>742
整形ありがとうございます。
やってることは似てそうなんですが、定数が違ってそうなのでもう少し弄ってみます。

746 名前:デフォルトの名無しさん mailto:sage [2010/06/07(月) 03:58:40 ]
4NDX と、X が出てくる理由が不明だ。
B595 と、9 が出てくる理由が不明だ。
こうなるはず、
8bit区切り
1c 68 ee 57 49 65 51 4e c9 c2 7a 57 97 27 19 ea
5bit区切り
3 11 14 E 1C 15 1A 9 C 15 8 14 1D 12 E 2 F 9 B 19 E 9 18 19 1D 8

747 名前:デフォルトの名無しさん mailto:sage [2010/06/07(月) 09:04:15 ]
Base32(WXYZが使われてる)と、Base32hex(0189が使われてる)があるそうですね。
面白そうなので作ってみたら >>746と同じ結果に。
Base32: DRUO4V2JMVIU5SOCPJLZOJYZ5I======
Base32hex: 3HKESLQ9CL8KTIE2F9BPE9OPT8======
>>745と全然違うなあ。
しかしBase32って超マイナーですね。

748 名前:748 mailto:sage [2010/06/07(月) 20:34:22 ]
> 1. そのソースコードが使われいるexe
> $ exec "1c68ee574965514ec9c27a57972719ea"
> 4NDXFOSLFKFHMTQT2K6LSOGPK
>
アナタの自作プログラム↑ソース↓
pc12.2ch.net/test/read.cgi/tech/1274617383/328
>
> 2. Base32エンコード
> $ echo "1c68ee574965514ec9c27a57972719ea" | java Base32encode
> S0QSUB595BKSK4B0QRLEPJ43A7
こっちのソース、またはソースのURLくれ。

749 名前:748 mailto:sage [2010/06/07(月) 22:36:19 ]
shr ((i * 5) mod 8)) and 31];
 ↓に変更(再コンパイル可能なら、だけど)
shr (11 - ((i * 5) mod 8))) and 31];


750 名前:デフォルトの名無しさん mailto:sage [2010/06/08(火) 01:00:38 ]
>>748
今確認したら結果が逆でした・・・汗

1. 移植したいプログラム ( Delphi )
ttp://jane.s89.xrea.com/test/read.cgi/kakolog/1090658524/583-585
> nghash.exe "1c68ee574965514ec9c27a57972719ea"
S0QSUB595BKSK4BOQRLEPJ43A7

2. 自作したプログラム ( Java )
ttp://pc12.2ch.net/test/read.cgi/tech/1274617383/328
% echo "1c68ee574965514ec9c27a57972719ea" | java Base32encode
4NDXFOSLFKFHMTQT2K6LSOGPK

Jane2chのNSFiles.txtで使われる、MD5をエンコードした無視画像リストを、
システムに組み込みたくて、移植してる次第です。・・・なんですが、力不足で全く移植できず

751 名前:デフォルトの名無しさん mailto:sage [2010/06/08(火) 09:57:52 ]
S0Q..L..はナンチャラは何なの?という疑問 0とL が混じってる。
1.Base32HEX エンコードだけをしてもこの値にはならないので、
  その部分だけのDelphiでは足りない。ソースは受け取ったが、
  ソース全部読む必要があるので、時間と人手がいる。
> nghash.exe "1c68ee574965514ec9c27a57972719ea"
S0QSUB595BKSK4BOQRLEPJ43A7

2.Base32HEX エンコードだけのソースなら、ネット検索すればあるはず。
  1.に関連して、>>749 はバグだと思ったけど、そのソースを生かすなら
  Base32HEXではない。逆にその部分だけを修正すればBase32HEX のソース
  を直せばいい。
また、>>749 shr の使い方を誰かDelphiで合ってるか確認してほしい。

752 名前:747 mailto:sage [2010/06/08(火) 10:53:30 ]
>>750
やっぱり。どうも変だなと思ってた。あと、ソースの頭にしっかり
//5bitエンコーディング関数 Base32ではない。
って書いてあるじゃない。最初は見落としてたの?

>>751
>>741の function EncodeB32 だけでちゃんと
S0QSUB595BKSK4BOQRLEPJ43A7
になるのを確認したので、これはBase32でもBase32hexでもないと思います。

>また、>>749 shr の使い方を誰かDelphiで合ってるか確認してほしい。
どう確認すればいいのか分かりませんが、そこだけ差し替えたら
D0N6FIA5A575IGMQATBLF69A03
になりましたよ。

Delphi始めて数ヶ月の初心者が頭突っ込んでスマソでした

753 名前:デフォルトの名無しさん mailto:sage [2010/06/08(火) 16:32:22 ]
いやいや、可能性が無いなら参考になった。>>752
以下の修正で目的の文字列になった。
参考になるURLがどこかに有ると思うが省略させてもらう。

MakeWord(byte1,byte2) の定義は byte1 | byte2 << 8
それと、shr ((i * 5) div 8)

BASE32の場合は
MakeWord(byte1,byte2) の定義を以下にする byte1 << 8 | byte2
それと、shr (11 - ((i * 5) div 8))



754 名前: ◆/91kCCQXBo mailto:sage [2010/06/08(火) 17:41:05 ]
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
char*EncodeB32(char*s){const char B32Char[32]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K'
,'L','M','N','O','P','Q','R','S','T','U','V'};int i,len;char*sa,*Result;if(s==NULL||*s==(char)NULL){return NULL;}len=(strlen(s)*8-
1)/5+1;sa=s;Result=calloc(len+1,1);for(i=0;i<=len-1;i++){Result[i]=B32Char[(((sa[(i*5)/8+0]&0xFF)|(sa[(i*5)/8+1]&0xFF)<<8)>>(((i*5
)%8)))&31];}return Result;}
int main(void){char*ans;ans=EncodeB32("\x1c\x68\xee\x57\x49\x65\x51\x4e\xc9\xc2\x7a\x57\x97\x27\x19\xea");if(ans)puts(ans);free(ans);}

755 名前:747 mailto:sage [2010/06/08(火) 23:02:43 ]
私も勉強がてらJavascriptに翻訳してみました。
出来る限り元ソースに忠実にしました。
ideone.com/bNeGf
DelphiもJavascriptもよく分かっていない初心者が書いてるので、激しいツッコミはご容赦下さい。

一応、ブックマークレット版。もちろん、末尾改行は全部除去して使ってね。
Javascript:function EncodeB32(s){function StringOfChar(C,N){var I,Z='';for(I=1;I<=N;++I)
{Z+=C;}return Z;}function MakeWord(H,L){return H|L<<8;}var i,len,B32Char=['0','1','2','3',
'4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V'],
Result=[];if(s==''){return '';}len=(s.length*8-1)/5+1;s+=StringOfChar('\x00',(len*5-1)/8+1-s.length);
for(i=0;i<=len-1;++i){Result[i+1-1]=B32Char[(MakeWord(s.charCodeAt((i*5)/8+1-1),
s.charCodeAt((i*5)/8+2-1))>>>((i*5)%8))&31];}return Result.join('');}
function HexToStr(H){var I,Result='';for(I=0;I<=H.length/2-1;++I)
{Result+=String.fromCharCode(parseInt(H.substr(I*2,2),16));}return Result;}
alert(EncodeB32(HexToStr('1c68ee574965514ec9c27a57972719ea')));

普段はごく簡単なブックマークレットしか作らないので、functionすら滅多に使いません。。。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<277KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef