(WINAPI)Midiシーケンサの製作(基本機能のみ)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
KEYONN_
記事: 70
登録日時: 13年前

(WINAPI)Midiシーケンサの製作(基本機能のみ)

#1

投稿記事 by KEYONN_ » 12年前

こんばんは。KEYONNです。
このウェブサイト内のアンドロイドの館にはお世話になっています。
(javaを覚えるのに、3日くらいかかりましたが、最近やってないせいか、忘れ気味…)

さて、あと、2日で、とあるプログラムを仕上げなくてはいけないのです。
このプログラムを
件名に書いたとおり、MIDIシーケンサを基本機能
レベル0.音が出る、
レベル1.マウスを使う
レベル2.スクロールさせる
レベル3.ノートを配置できる
レベル4.ノートをスクロールバーで移動できる
レベル5.音を再生ボタンで再生できる

この6つの機能を備えたプログラムを書いています。
しかし、レベル4で躓いてしまいました。

スクロールバーは縦スクロールバーと、横スクロールバーがあり、
どちらも、スクロールさせると、スクロール方向に、動くのですが、
再度、ノートを配置すると、間違った所に配置されてしまいます。

コンパイラはVisualC++6.0です。
リソースエディタから、ダイアログボックスをつくり、WinMain内でDialogBoxマクロを使って、
動かしています。

何が間違っているのか、よく分かりません。教えて欲しいです。
添付ファイル
MIDI_VC.zip
(1.41 MiB) ダウンロード数: 146 回

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#2

投稿記事 by KEYONN_ » 12年前

//コメント少なくて真にすみませんでした。(// とか /* */が
//今すぐ、コメントを多くしたソースだけアップする用意をするので、待っててください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#3

投稿記事 by softya(ソフト屋) » 12年前

ごめんなさい変数が多すぎると共通化されていない部分が多く他人の私では追いきれません。 [追記] 関数化・クラス化・構造体などまとめられるべきところが放置されています。tbl3とか2ヶ所も出てくる意味が無いと思いますが。
とりあえず、デバッグ手法を教えますので数値変化を追いかけてみて下さい。

「簡単RPG講座 番外編。 デバッグ入門 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&b=982&c=2
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#4

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:ごめんなさい変数が多すぎると共通化されていない部分が多く他人の私では追いきれません。 [追記] 関数化・クラス化・構造体などまとめられるべきところが放置されています。tbl3とか2ヶ所も出てくる意味が無いと思いますが。
とりあえず、デバッグ手法を教えますので数値変化を追いかけてみて下さい。

「簡単RPG講座 番外編。 デバッグ入門 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&b=982&c=2
ソフト屋さんの方法で試してみます。
あと、ソースをちょっとだけまとめてみたので、見てください。
添付ファイル
Main.cpp
(11.27 KiB) ダウンロード数: 128 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#5

投稿記事 by softya(ソフト屋) » 12年前

これは何らかの課題とか提出用のものでしょうか?
もし、そうならソースコードの書き方として問題点がすごくありますが指定したほうが良いのでしょうか?
とりあえず動けば良いなら、このまま続けても良いと思いますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#6

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:これは何らかの課題とか提出用のものでしょうか?
もし、そうならソースコードの書き方として問題点がすごくありますが指定したほうが良いのでしょうか?
とりあえず動けば良いなら、このまま続けても良いと思いますが。
とりあえず動けば良いので、このまま続けて欲しいです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#7

投稿記事 by softya(ソフト屋) » 12年前

分かりました。
ただインデントだけは綺麗に書いて下さい。すごく見づらいです。
あと、ちょっと離れますのでしばらく返答ができません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#8

投稿記事 by softya(ソフト屋) » 12年前

この表示ですが元から371が足されているようです。
Rectangle( hdc, N.StartXRtn( i ) - nPos/* + 371*/, N.StartYRtn( i ) - vPos,
N.EndXRtn( i ) - nPos/* + 371*/, N.EndYRtn( i ) - vPos );

[追記] 他にも表示上の問題がありますが、マジックナンバーやら色々出てくるので何がしたいのか分からない状況です。
座標に足す371と言うマジックナンバーは何なのでしょう?

一番の問題は、このシーケンサの目的としている操作が分かっていなことかも知れません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

KEYONN
記事: 37
登録日時: 12年前
住所: 静岡県

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#9

投稿記事 by KEYONN » 12年前

softya(ソフト屋) さんが書きました:この表示ですが元から371が足されているようです。
Rectangle( hdc, N.StartXRtn( i ) - nPos/* + 371*/, N.StartYRtn( i ) - vPos,
N.EndXRtn( i ) - nPos/* + 371*/, N.EndYRtn( i ) - vPos );

[追記] 他にも表示上の問題がありますが、マジックナンバーやら色々出てくるので何がしたいのか分からない状況です。
座標に足す371と言うマジックナンバーは何なのでしょう?

一番の問題は、このシーケンサの目的としている操作が分かっていなことかも知れません。
マジックナンバー371は、横スクロールバーのスクロール値nPosの初期値です。
いままでのシーケンサは、縦にピアノロール、横に時間軸を取っていましたが、
このシーケンサは、横にピアノロール、縦に時間軸をとります。

KEYONN
記事: 37
登録日時: 12年前
住所: 静岡県

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#10

投稿記事 by KEYONN » 12年前

書くのを忘れていました。ネットカフェからの書き込みです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#11

投稿記事 by softya(ソフト屋) » 12年前

KEYONN さんが書きました:マジックナンバー371は、横スクロールバーのスクロール値nPosの初期値です。
元のコードですが

コード:

						Rectangle(hdc,N.StartXRtn(i)-nPos+371,N.StartYRtn(i)-vPos,
							N.EndXRtn(i)-nPos+371,N.EndYRtn(i)-vPos);
登録時に
N.Search(M.StartX+nPos,M.StartY+vPos,M.StartX+16+nPos,M.EndY+vPos,note);
としてますので
表示でN.StartXRtn(i)-nPos+371だと
M.StartX+nPos-nPos+371の計算と同義です。これは意図通りですか?

ちなみにN.Searchと言う名前は機能を表現していないのでよくない関数名です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

KEYONN
記事: 37
登録日時: 12年前
住所: 静岡県

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#12

投稿記事 by KEYONN » 12年前

softya(ソフト屋) さんが書きました:
KEYONN さんが書きました:マジックナンバー371は、横スクロールバーのスクロール値nPosの初期値です。
元のコードですが

コード:

						Rectangle(hdc,N.StartXRtn(i)-nPos+371,N.StartYRtn(i)-vPos,
							N.EndXRtn(i)-nPos+371,N.EndYRtn(i)-vPos);
登録時に
N.Search(M.StartX+nPos,M.StartY+vPos,M.StartX+16+nPos,M.EndY+vPos,note);
としてますので
表示でN.StartXRtn(i)-nPos+371だと
M.StartX+nPos-nPos+371の計算と同義です。これは意図通りですか?
ちなみにN.Searchと言う名前は機能を表現していないのでよくない関数名です。
意図通りというか、計算の仕方がよく分からなかったので、ソースを改造して、でたらめの計算をしている可能性があります。
本当は、横スクロールバーが、右にいけば、ノートは、左に行って欲しいんです。そして、横スクロールバーが左にいけば
ノートは右にいってほしいんです。

N.Searchでは、よくない関数名なのですか…、N.NoWorkSearchとか、N.PrepareOfDrawなんてどうでしょう。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#13

投稿記事 by softya(ソフト屋) » 12年前

KEYONN さんが書きました:意図通りというか、計算の仕方がよく分からなかったので、ソースを改造して、でたらめの計算をしている可能性があります。
本当は、横スクロールバーが、右にいけば、ノートは、左に行って欲しいんです。そして、横スクロールバーが左にいけば
ノートは右にいってほしいんです。
何かベースにしているソースコードがあって把握していない事があるんですね?
少なくともN.StartXRtn(i)を使った表示時に371を足すのやめれはスクロールには追従しているようには見えます。
※ 描いちゃいけない所に描くとかガードをしていない問題は除きます。
KEYONN さんが書きました:N.Searchでは、よくない関数名なのですか…、N.NoWorkSearchとか、N.PrepareOfDrawなんてどうでしょう。
Searchの意味は検索ですが実際の動作はどうみてもテーブル登録です。検索はテーブル登録のための行為で主目的はテーブル登録ですよね。
なので他の人から見れば、関数名と実際の動作が食い違う読みにくいソースコードです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

KEYONN
記事: 37
登録日時: 12年前
住所: 静岡県

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#14

投稿記事 by KEYONN » 12年前

softya(ソフト屋) さんが書きました:
KEYONN さんが書きました:意図通りというか、計算の仕方がよく分からなかったので、ソースを改造して、でたらめの計算をしている可能性があります。
本当は、横スクロールバーが、右にいけば、ノートは、左に行って欲しいんです。そして、横スクロールバーが左にいけば
ノートは右にいってほしいんです。
何かベースにしているソースコードがあって把握していない事があるんですね?
少なくともN.StartXRtn(i)を使った表示時に371を足すのやめれはスクロールには追従しているようには見えます。
※ 描いちゃいけない所に描くとかガードをしていない問題は除きます。
KEYONN さんが書きました:N.Searchでは、よくない関数名なのですか…、N.NoWorkSearchとか、N.PrepareOfDrawなんてどうでしょう。
Searchの意味は検索ですが実際の動作はどうみてもテーブル登録です。検索はテーブル登録のための行為で主目的はテーブル登録ですよね。
なので他の人から見れば、関数名と実際の動作が食い違う読みにくいソースコードです。
猫でも分かるWindowsプログラミング第2版を参考にしています。しかし、スクロールバーの機能の解説は少ししかなくて、
結局ネットを使って、調べました。あと、371を足すのをやめたら、確かにスクロールに追従しているのですが、
ずれて表示されます。
この差は、一体何なのでしょうか?
あと、テーブル登録が主目的なので、N.RegistTableが一番分かりやすい関数名でしょうか。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#15

投稿記事 by softya(ソフト屋) » 12年前

KEYONN さんが書きました:猫でも分かるWindowsプログラミング第2版を参考にしています。しかし、スクロールバーの機能の解説は少ししかなくて、
結局ネットを使って、調べました。あと、371を足すのをやめたら、確かにスクロールに追従しているのですが、
ずれて表示されます。
この差は、一体何なのでしょうか?
そもそもマウスからクリック位置を計算したM.StartX の値が正しいことは確認されていますか?
スクロール前からズレている気がするのですが。
KEYONN さんが書きました: あと、テーブル登録が主目的なので、N.RegistTableが一番分かりやすい関数名でしょうか。
一番かどうかはわかりませんが、Searchよりもすごく良いことは確かです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#16

投稿記事 by YuO » 12年前

softya(ソフト屋) さんが書きました:
KEYONN さんが書きました:あと、テーブル登録が主目的なので、N.RegistTableが一番分かりやすい関数名でしょうか。
一番かどうかはわかりませんが、Searchよりもすごく良いことは確かです。
せめてRegisterTableに……。
# register 【自動】 登録する

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#17

投稿記事 by softya(ソフト屋) » 12年前

そうですね動詞であるregisterの方が良いです。ちなみにregistと言う英単語は存在しないです。

[追記] M.RegisterTable()と言うMも意味不明なので、もっと明確な名前を与えるべきではあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#18

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:そうですね動詞であるregisterの方が良いです。ちなみにregistと言う英単語は存在しないです。

[追記] M.RegisterTable()と言うMも意味不明なので、もっと明確な名前を与えるべきではあります。
MOUSE.RegisterTableみたいな感じでしょうか?
あと、
VisualC++6.0だと、M.StartXの値はずれていなかったのですが、
VisualC++2008だと、ずれて表示されました。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#19

投稿記事 by KEYONN_ » 12年前

もしかしたら、画面解像度によってずれるのかもしれないです。
他の環境だと、もっと違くなるのかもしれないです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#20

投稿記事 by softya(ソフト屋) » 12年前

xpスタイルと2000などのウィンドウスタイルの違いかも知れません。
とりあえず、急ぐならVC++6.0で合わせれば良いと思います。
本気で取り組みたいなら、締め切り時間を無視してどちらでも動くものを作るべきです。

見間違えてました。M.RegisterTable()ではなくN.RegisterTable()ですね。MはmouseでNはnoteですか。
ただ、Mouseは本質名でないような?マウス座標ではなく、ノートの一要素の値を保持しているような気がするのですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#21

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:xpスタイルと2000などのウィンドウスタイルの違いかも知れません。
とりあえず、急ぐならVC++6.0で合わせれば良いと思います。
本気で取り組みたいなら、締め切り時間を無視してどちらでも動くものを作るべきです。

見間違えてました。M.RegisterTable()ではなくN.RegisterTable()ですね。MはmouseでNはnoteですか。
ただ、Mouseは本質名でないような?マウス座標ではなく、ノートの一要素の値を保持しているような気がするのですが。
ソフト屋さんへ
どちらにせよ、私は、このシーケンサーソフトを本気で作りたいです。
ソースは見づらくても、動くものが出来れば良い?というと、ソフトウェア開発者として、
何を考えているんだ?と思われるかもしれないですが、それは、僕の独創的な感じから
出てくる問題です。

このシーケンサーソフトは、最初VisualBasic6.0で作っていたのですが、諸問題が発生し、描画や、
タイマーの遅さが原因でVisualC++6.0で再開発することになりました。その時は(VisualBasic版)
スクロールは考えずに、2オクターブだけの限定的なソフトでした。#もきちんと使えていました。
音符の長さは、与えられた範囲内をドラッグするだけで、指定しました。このソースを元に
作れば良いのかなと思いました。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#22

投稿記事 by KEYONN_ » 12年前

VisualBasic版の画像(スクリーンショット)と実行ファイルです。
よければどうぞ
添付ファイル
VMIDI03.zip
(17.41 KiB) ダウンロード数: 113 回
cde.jpg

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#23

投稿記事 by softya(ソフト屋) » 12年前

厳しく書きますが、独創的なのは良いのですが名前や値の扱いなど分かりづらいのが原因でミスを連発しては本末転倒です。書きやすさ・読みさすさは自分のためでも有ります。
根本的な所ではクラスや関数や構造体などの使い所がちゃんと出来ていないのは独創的なのと別の問題です。

あと他の人に見てもらう以上は、読みやすさは配慮として必要ではないでしょうか?
ハッカーの中には読みやすさは不要と独自の哲学を持つ人もいますが、彼らは自分で何とかしてしまうので全然構わないです。

本気で作りたいのなら、まず元となるソースコードの意味を理解した上で、ちゃんと設計して作られることを考えるべきだと思います。
KEYONN_ さんが書きました: このシーケンサーソフトは、最初VisualBasic6.0で作っていたのですが、諸問題が発生し、描画や、
タイマーの遅さが原因でVisualC++6.0で再開発することになりました。その時は(VisualBasic版)
スクロールは考えずに、2オクターブだけの限定的なソフトでした。#もきちんと使えていました。
音符の長さは、与えられた範囲内をドラッグするだけで、指定しました。このソースを元に
作れば良いのかなと思いました。
結局同じ問題に突き当たる気がします。Win32APIで作る以上は今のシーケンサのコードと基本的な制御は大差ないものになるでしょう。
VBは難しい所を隠蔽してくれるから楽なので、C++とWin32APIでは理解しないと行けない所が複雑になります。
それにシーケンスを演奏する場合は、マルティメディアタイマーやスレッドを使わないとスムーズに動かないと思います。普通のタイマーだと同じ問題に突き当たりませんか?
VB6版を触った印象は、普通のタイマーを利用している限り解消されない気がしました。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#24

投稿記事 by softya(ソフト屋) » 12年前

中途半端ですが、読みやすくしてみました。勝手な解釈でコメントも入れてあります。名前の意味づけは不十分です。
表示系でガードが甘かったところもガードしてみましたが、もっと真面目にしないと見栄えはよろしく有りません。
► スポイラーを表示
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#25

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:厳しく書きますが、独創的なのは良いのですが名前や値の扱いなど分かりづらいのが原因でミスを連発しては本末転倒です。書きやすさ・読みさすさは自分のためでも有ります。
根本的な所ではクラスや関数や構造体などの使い所がちゃんと出来ていないのは独創的なのと別の問題です。

あと他の人に見てもらう以上は、読みやすさは配慮として必要ではないでしょうか?
ハッカーの中には読みやすさは不要と独自の哲学を持つ人もいますが、彼らは自分で何とかしてしまうので全然構わないです。

本気で作りたいのなら、まず元となるソースコードの意味を理解した上で、ちゃんと設計して作られることを考えるべきだと思います。
KEYONN_ さんが書きました: このシーケンサーソフトは、最初VisualBasic6.0で作っていたのですが、諸問題が発生し、描画や、
タイマーの遅さが原因でVisualC++6.0で再開発することになりました。その時は(VisualBasic版)
スクロールは考えずに、2オクターブだけの限定的なソフトでした。#もきちんと使えていました。
音符の長さは、与えられた範囲内をドラッグするだけで、指定しました。このソースを元に
作れば良いのかなと思いました。
結局同じ問題に突き当たる気がします。Win32APIで作る以上は今のシーケンサのコードと基本的な制御は大差ないものになるでしょう。
VBは難しい所を隠蔽してくれるから楽なので、C++とWin32APIでは理解しないと行けない所が複雑になります。
それにシーケンスを演奏する場合は、マルティメディアタイマーやスレッドを使わないとスムーズに動かないと思います。普通のタイマーだと同じ問題に突き当たりませんか?
VB6版を触った印象は、普通のタイマーを利用している限り解消されない気がしました。
>>クラスや関数、構造体の使い方がちゃんと出来ていないのは独創的なのと別の問題です。
そうですね。努力すれば、誰でも出来ることと、独創的なのは違いますね。

>>本気で作りたいのなら、まず元となるソースコードの意味を理解した上で、
>>ちゃんと設計して作られることを考えるべきだと思います。
設計の仕方をまず学ぶべきでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#26

投稿記事 by softya(ソフト屋) » 12年前

KEYONN_ さんが書きました:設計の仕方をまず学ぶべきでしょうか?
設計の仕方を学ぶと言うよりも、今まで設計した事が無いのではないでしょうか?
サンプルにツギハギして形にすることばかりを繰り返しているとプログラム構造を明確に整理する癖も付いていないと思います。
そういう意味で、まずリファクタリングが勉強になります。
プログラムの流れの無駄を整理して共通関数化・クラス化できる処理を整理します。データも意味の共通のものはクラスか構造体にまとめます。
マジックナンバーはconstにするとか、enumするとか、計算で求まるなら計算で求めます。
こうするだけで驚くほどプログラムはすっきりします(行数は増える可能性があります)。

簡易な設計ですが設計は、まずGUI画面を設計して自動入手不能なサイズなどの情報をconstで記述します。
つぎに画面の各要素を制御するために必要な変数やテーブルを書きだして出来るだけ構造体やクラスの形にまとめます。
次に機能として処理をするに必要なアクションと必要となると思われる関数やクラスを書き出します。
最初は大雑把でも良いので意識するだけでだいぶ変わると思います。
あとは組み立てながらリファクリングも適時行いましょう。

今までのコードや私のコードは参考程度に留めて、オリジナルのコードを書いてみて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#27

投稿記事 by KEYONN_ » 12年前

コード:

//2012/2/18
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <string.h> //memset, strcat, strcpy
#include <stdio.h> //sprintf
#include <math.h> //atof
#include <stdlib.h> //atof
#include "resource.h"
#include<mmsystem.h>

#define MAX_NOTE 512
#define MIDIMSG(status,channel,data1,data2) ( (DWORD)((status<<4) | channel | (data1<<8) | (data2<<16)) )

int Timer=0;

class Note{
private://メンバ変数はprivateにして、カプセル化
	int StartX[MAX_NOTE];//
	int StartY[MAX_NOTE];//初期座標
	int EndX[MAX_NOTE];
	int EndY[MAX_NOTE];//終了座標
	int ExistFlag[MAX_NOTE];//存在フラグ
	int note[MAX_NOTE];//ノート番号
	int program[MAX_NOTE];//プログラム番号
	int length[MAX_NOTE];//長さ[
	int StartTime[MAX_NOTE];//開始時間
public:
	//カプセル化
	int StartXRtn(int i)
	{
		return StartX[i];//初期座標Xを返すメソッド
	}
	int StartYRtn(int i)
	{
		return StartY[i];//初期座標Yを返すメソッド
	}
	int EndXRtn(int i)
	{
		return EndX[i];//終了座標Xを返すメソッド
	}
	int EndYRtn(int i)
	{
		return EndY[i];//終了座標Yを返すメソッド
	}
	int ExistFlagRtn(int i)
	{
		return ExistFlag[i];//存在フラグを返すメソッド
	}
	int NoteRtn(int i)
	{
		return note[i];//ノート番号を返すメソッド
	}
	int lengthRtn(int i)
	{
		return length[i];
	}
	Note()
	{
		//コンストラクタ(クラス生成時(インスタンス化した時)に呼び出される戻り値のない特殊なメソッド
		int i;
		for(i=0;i<MAX_NOTE;i++)
		{
			ExistFlag[i]=0;//0にセットしないと、何故か、描画されない
		}
	}
	int GetMouseCursor(POINT *Start,POINT *End,int Index) 
	{
        
		if( ExistFlagRtn(Index)==1) 
		{
			Start->x = StartXRtn(Index);
			Start->y = StartYRtn(Index);
			End->x=StartXRtn(Index)+16;
			End->y= StartYRtn(Index)+lengthRtn(Index);
			return 1;
		}
        
		return 0;
	}
	void Touroku( int x,int y,int l,int n ) {
        for( int i=0; i < MAX_NOTE; i++ ) {
            //線形探索
            if( ExistFlag[i] == 0 ) {
                ExistFlag[i] = 1;
                program[i] = 0;
				StartX[i] = x;
				StartY[i] = y;
                note[i] = n;
                StartTime[i] = y - 128;
                length[i] = l;
                break;
            }
        }
    }
	void PlayNoteOfMidi()
	{
		Timer=1;
	}
	void StopNoteOfMidi()
	{
		Timer=0;
	}
};

typedef struct Mouse{//Mouse構造体
	int MoveY;//動いているY
	int MoveFlag;//動いているかのフラグ
	int ClickFlag;//クリックフラグ
	int StartX;//クリック初期の座標X
	int StartY;//クリック初期の座標Y
	int EndX;//クリック終了の座標X
	int EndY;//クリック終了の座標Y
	POINTS clc;//POINTS型のclc
}Mouse;

Mouse MOUSE;//構造体MOUSE
Note NOTE;//クラスのインスタンス化
int nPos=371,vPos=60;//スクロール変数nPosと、vPos
HMIDIOUT hMidi;
BYTE note=0x3C,velocity=0x40;//note番号、ベロシティを宣言

HINSTANCE hInst;
LRESULT CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM);//ダイアログプロシージャ
const int NOTE_WIDTH = 16;//ノートの幅


int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
                   LPSTR lpsCmdLine, int nCmdShow)
{
	hInst=hCurInst;
    DialogBox(hCurInst, TEXT("MYDLG"), NULL, (DLGPROC)MyDlgProc);//ダイアログボックス"MYDLG"を呼び出す
    return 0;
}


POINT ClickOfPic2(HWND hWnd)
	{
		POINT pt;
		RECT rc;
		POINT xy;
		GetCursorPos(&pt); //マウスポインタの位置取得
		ScreenToClient(hWnd,&pt); //スクリーン座標→クライアント座標
		xy.x = pt.x;
		xy.y = pt.y;
		GetWindowRect(hWnd,&rc); //コントロールの位置取得
		pt.x = rc.left;
		pt.y = rc.top;
		ScreenToClient(hWnd,&pt); //スクリーン座標→クライアント座標
		xy.x-=pt.x;
		xy.y-=pt.y;
		return xy;
	}
BYTE PointOfNote(POINTS clc,HWND hWnd)
{
	int tbl3[]={0,2,  4 ,5, 7,  9,11,12,14,16,17,19,21,23,24,26,28,29,31,33,35,
				36,38,40, 41,43, 45, 47, 48,  50,52, 53, 55,  57, 59,
				60,62,64,65,67,69,71,72,74,76,77,79,81,83,84,86,88,89,91,93,95,
			//  c3 d3 e3 f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5 d5 e5 f5 g5 a5 b5
				96,98,100,101,103,105,107,108,110,112,113,115,117,119,
			//	c6 d6 e6  f6  g6  a6  b6   c7  d7  e7 f7   g7  a7  b7
				120,122,124,125,127};//#♭なしの音
	int tbl4[]={1,3,-1,6,8,10,-1,13,15,-1,18,20,22,-1,25,27,-1,30,32,34,-1,
				37,39,42,44,46,-1,49,51,-1,54,56,58,-1,
				61,63,-1,66,68,70,-1,73,75,-1,78,80,82,-1,85,87,-1,90,92,94,-1,
				97,99,-1,102,104,106,-1,109,111,-1,114,116,118,-1,
				121,123,-1,126};//#の音
	BYTE note;
	POINT xy;
	xy=ClickOfPic2(hWnd);
	
	MOUSE.clc.x=((clc.x+5)/NOTE_WIDTH)*NOTE_WIDTH;
	note=tbl3[(clc.x+nPos)/NOTE_WIDTH-2];
	if(clc.y<100)
	{
		note=tbl4[(clc.x+nPos-8)/NOTE_WIDTH-1];
	}
	if(note!=-1)//-1じゃなければ音を出す
		midiOutShortMsg(hMidi,MIDIMSG(0x9,0x0,note,velocity));
	return note;
}

int SelectNoteLength(int subY)
{
	switch(subY)
	{
	case 16:
		return 32;
	case 32:
		return 16;
		break;
	case 48:
		return 8;
		break;
	case 64:
		return 4;
		break;
	case 80:
		return 2;
		break;
	case 96:
		return 1;
	}
	return 0;
}

LRESULT CALLBACK MyDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    static HBITMAP hBmp[2];//HBITMAP型のhBmpを宣言
	static BITMAP bmp_info[2];
	static int w,h,w2,h2;//画像の高さ、幅を宣言
	static HDC hdc,hdc_mem[2];//デバイスコンテキストハンドル
	static PAINTSTRUCT ps;
	static HWND hPic,hPic2,hScroll1,vScroll1,hList1,hMain;//ウィンドウハンドルの宣言
	
    static BYTE program=0;//プログラム番号は0(ピアノ)
	static 
	int i;//iを宣言
	HPEN hPen1,hPen2;//HPEN型宣言
	static int length=0;//♪の長さ
	
    
	
	switch (msg) {
		case WM_HSCROLL://横スクロールバーのイベント
			if(lp!=(LPARAM)hScroll1)
				return FALSE;
			switch(LOWORD(wp))
			{
				case SB_LINELEFT:
					nPos--;
					if(nPos<0) nPos=0;
					break;
				case SB_LINERIGHT:
					nPos++;
					if(nPos>743)
					{
						nPos=743;
					}
					break;
				case SB_PAGELEFT:
					nPos-=16;
					if(nPos<0) nPos=0;
					break;
				case SB_PAGERIGHT:
					nPos+=16;
					if(nPos>743) nPos=743;
					break;
				case SB_THUMBTRACK:
					nPos=HIWORD(wp);
					break;
				case SB_THUMBPOSITION:
					nPos=HIWORD(wp);
					break;
				}
			ScrollBar_SetPos(hScroll1,nPos,TRUE);//スクロール値をセットする
			InvalidateRect(hPic,NULL,TRUE);
			InvalidateRect(hPic2,NULL,TRUE);
			return TRUE;
		case WM_VSCROLL://縦スクロールバーのイベント
			if(lp!=(LPARAM)vScroll1)
				return FALSE;
			switch(LOWORD(wp))
			{
				case SB_LINELEFT:
					vPos--;
					if(vPos<0) vPos=0;
					break;
				case SB_LINERIGHT:
					vPos++;
					if(vPos>743)
					{
						vPos=743;
					}
					break;
				case SB_PAGELEFT:
					vPos-=16;
					if(vPos<0) vPos=0;
					break;
				case SB_PAGERIGHT:
					vPos+=16;
					if(vPos>743) vPos=743;
					break;
				case SB_THUMBTRACK:
					vPos=HIWORD(wp);
					break;
				case SB_THUMBPOSITION:
					vPos=HIWORD(wp);
					break;
				}
			ScrollBar_SetPos(vScroll1,vPos,TRUE);//スクロール値をセットする
			InvalidateRect(hPic2,NULL,TRUE);
			return TRUE;
        case WM_INITDIALOG:
			
			//IDからウィンドウハンドルを得る
			hPic=GetDlgItem(hWnd,IDC_STATIC01);
			hPic2=GetDlgItem(hWnd,IDC_STATIC02);
			hScroll1=GetDlgItem(hWnd,IDC_SCROLLBAR1);
			vScroll1=GetDlgItem(hWnd,IDC_SCROLLBAR2);
			hList1=GetDlgItem(hWnd,IDC_LIST1);
			hMain=GetParent(hWnd);
			//リソースBMPをロード
            hBmp[0]=LoadBitmap(hInst,TEXT("MYBMP"));
			hBmp[1]=LoadBitmap(hInst,TEXT("MYBMP2"));
			
			//タイマーをセット
			SetTimer(hWnd,100,100,NULL);
			
			//デバイスコンテキストを得る
			hdc=GetDC(hWnd);
			hdc_mem[0]=CreateCompatibleDC(hdc);//互換性のあるBMPを作成
			SelectObject(hdc_mem[0],hBmp[0]);//オブジェクトを選択
			DeleteObject(hBmp[0]);//削除
			hdc_mem[1]=CreateCompatibleDC(hdc);//互換性のあるBMPを作成
			SelectObject(hdc_mem[1],hBmp[1]);//オブジェクトを選択
			DeleteObject(hBmp[1]);//削除
			ReleaseDC(hWnd,hdc);//デバイスコンテキストをリリース

			midiOutOpen(&hMidi , MIDIMAPPER , 0 , 0 , 0);//MIDIMAPPERをオープン
			midiOutShortMsg(hMidi,MIDIMSG(0xC,0,program,0));//最初の初期化

			ScrollBar_SetRange(hScroll1,0,743,TRUE);//範囲を選択
			ScrollBar_SetPos(hScroll1,nPos,TRUE);//位置を選択
			ScrollBar_SetRange(vScroll1,0,16*4*80,TRUE);
			ScrollBar_SetPos(vScroll1,vPos,TRUE);


            return TRUE;
		case WM_DESTROY://ウィンドウが破棄されたら
			DeleteDC(hdc_mem[0]);
			DeleteDC(hdc_mem[1]);
			midiOutReset(hMidi);
            midiOutClose(hMidi);
			
			PostQuitMessage(0);
			break;

		case WM_CLOSE://ウィンドウ閉じる
			DeleteDC(hdc_mem[0]);
			DeleteDC(hdc_mem[1]);

			midiOutReset(hMidi);
			midiOutClose(hMidi);

			DestroyWindow(hWnd);
			break;
		case WM_TIMER://SetTimerでタイマーがセットされる
			InvalidateRect(hPic,NULL,TRUE);
			InvalidateRect(hPic2,NULL,TRUE);
			InvalidateRect(hList1,NULL,TRUE);
			InvalidateRect(hMain,NULL,TRUE);
			break;
		case WM_RBUTTONUP://デバッグ用イベント
			{
			POINT xy;
			xy=ClickOfPic2(hPic2);

			char str[100];
			sprintf(str,"x=%d y=%d",xy.x,xy.y);
			MessageBox(hWnd,"OK",str,MB_OK);
			}
				break;
		case WM_LBUTTONDOWN:    //左クリック 鍵盤を押す
			{
			
			POINT xy;
			xy=ClickOfPic2(hPic2);
			MOUSE.clc=MAKEPOINTS(lp);
			note=PointOfNote(MOUSE.clc,hPic);

            if(MOUSE.clc.y>128)//clcが128以上なら
			{	MOUSE.ClickFlag=1;//クリックしているフラグをON
				MOUSE.StartX=xy.x/NOTE_WIDTH*NOTE_WIDTH;
				MOUSE.StartY=xy.y/NOTE_WIDTH*NOTE_WIDTH;
			}
			MOUSE.ClickFlag =1;
			InvalidateRect(hPic2,NULL,TRUE);
			}return 0;
        case WM_LBUTTONUP:    //鍵盤を離す
			{
			POINT xy;
			//char str[100];
			xy=ClickOfPic2(hPic2);

            midiOutShortMsg(hMidi,MIDIMSG(0x9,0x0,note,0));//消音
            MOUSE.ClickFlag=0;//クリックしているフラグをOFF
			MOUSE.EndX=xy.x;//終了座標のセット
			MOUSE.EndY=xy.y/NOTE_WIDTH*NOTE_WIDTH;
			InvalidateRect(hPic2,NULL,TRUE);//hPic2の再描画
			MOUSE.MoveFlag=0;//動いているフラグをOFF
			POINT Pnt;//POINT型のPntを宣言
			Pnt.x=MOUSE.StartX + nPos;//
			Pnt.y=MOUSE.StartY + vPos;
			NOTE.Touroku(Pnt.x,Pnt.y,MOUSE.EndY-MOUSE.StartY,note);
			//sprintf(str,"%d:%d",note,SelectNoteLength(MOUSE.EndY-MOUSE.StartY));
			//ListBox_AddString(hList1,str);
			//InvalidateRect(hWnd,NULL,TRUE);
			MOUSE.ClickFlag =0;
			}
			return 0;
		
		case WM_MOUSEMOVE:
			{
			POINT xy;
			xy=ClickOfPic2(hPic2);
			
			MOUSE.MoveY=xy.y/NOTE_WIDTH*NOTE_WIDTH;//16で割って、16をかける
			MOUSE.MoveFlag=1;//MoveFlagをON
				
			MOUSE.clc=MAKEPOINTS(lp);///clcにマウスカーソルの座標が入る
			if(MOUSE.ClickFlag ==1 && MOUSE.clc.y<128)//クリックしている時だけ鳴らす
				note=PointOfNote(MOUSE.clc,hPic);
			InvalidateRect(hPic2,NULL,TRUE);//hPic2を再描画
			}
			return 0;
		case WM_PAINT:
			{
				HPEN hPen,hOldPen;
				HBRUSH hBrush[2],hOldBrush[2];
				
				int tbl[]={2,2,1,2,2,2,1};
			int X0=nPos/NOTE_WIDTH,X1=(nPos+440)/NOTE_WIDTH;
			hdc=BeginPaint(hPic,&ps);
				GetObject(hBmp[0],(int)sizeof(BITMAP),&bmp_info[0]);
				w=bmp_info[0].bmWidth;
				h=bmp_info[0].bmHeight;
				for(i=X0;i<X1;i++)
					BitBlt(hdc,i*NOTE_WIDTH-nPos,0,w,h,hdc_mem[0],0,0,SRCCOPY);
				
				GetObject(hBmp[1],(int)sizeof(BITMAP),&bmp_info[1]);
				w=bmp_info[1].bmWidth;
				h=bmp_info[1].bmHeight;
				for(i=X0;i<X1;i++)
					BitBlt(hdc,i*16+tbl[i%7]*NOTE_WIDTH-8-nPos,0,w,h,hdc_mem[1],0,0,SRCCOPY);
				
				
				
			EndPaint(hPic,&ps);
			

			hdc=BeginPaint(hPic2,&ps);
				hBrush[0]=CreateSolidBrush(RGB(245,245,245));
				hOldBrush[0]=(HBRUSH)SelectObject(hdc,hBrush[0]);
				Rectangle(hdc,0,0,440,120);
				Rectangle(hdc,-12,0,440,120);
				hPen1=CreatePen(PS_SOLID,1,RGB(0,0,0));
				SelectObject(hdc,hPen1);
				for(i=X0;i<X1;i++)
				{
					MoveToEx(hdc,i*16-nPos,0,NULL);
					LineTo(hdc,i*NOTE_WIDTH-nPos,120);
				}
				hBrush[1]=CreateSolidBrush(RGB(0,120,255));
				hOldBrush[1]=(HBRUSH)SelectObject(hdc,hBrush[1]);
				if(MOUSE.ClickFlag==1 && MOUSE.MoveFlag==1)
					Rectangle(hdc,MOUSE.StartX,MOUSE.StartY,MOUSE.StartX+16,MOUSE.MoveY);
				else{
					if(MOUSE.StartY-vPos>0)
						Rectangle(hdc,MOUSE.StartX-nPos+371,MOUSE.StartY-vPos,MOUSE.StartX+16-nPos+371,MOUSE.EndY-vPos);
					
				}

				for(i=0;i<MAX_NOTE;i++)
				{
					POINT StartPoint,EndPoint;
					if( NOTE.GetMouseCursor(&StartPoint,&EndPoint,i) ) {
						//  表示座標に補正。
						StartPoint.x-=nPos;
						StartPoint.y-=vPos;
						EndPoint.x-=nPos;
						EndPoint.y-=vPos;
						//
						if((StartPoint.x>=0)&&(EndPoint.x<440)&&(StartPoint.y>=0)&&(EndPoint.y<120))
						{
							Rectangle( hdc, StartPoint.x, StartPoint.y, EndPoint.x, EndPoint.y);
						}
					}
				}
				DeleteObject(hPen1);
				DeleteObject(hBrush[0]);
				DeleteObject(hBrush[1]);
			EndPaint(hPic2,&ps);
			}
			return TRUE;
        case WM_COMMAND:
            switch (LOWORD(wp)) {
                case IDC_BUTTON1:
                    //Playボタン
					NOTE.PlayNoteOfMidi();
					
					//EndDialog(hWnd, 0);
                    return TRUE;
                case IDC_BUTTON2:
					NOTE.StopNoteOfMidi();
					vPos=0;
                    //Stopボタン
                    return TRUE;
            }
            break;
		
    }
    return FALSE;
}
オリジナルではないですが、一応自分なりに工夫したつもりです。
あと、WIN32APIからMFCとか、VBに逃げたくなりました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#28

投稿記事 by softya(ソフト屋) » 12年前

別にMFCは逃げではないと思いますが同じぐらい苦労すると思います。MFCの実体はWin32APIですからね。作っていると色々とAPIの姿が見え隠れします。
ちなみにVB6よりも今時のVB.NETの方が速度的には早くなっています。
どっちしろ、長いプログラムを組むためにはリファクタリングやらマメな関数化とかやらなければいけないことは沢山あります。

新しいのを見ましたが、結局画像の描画領域の問題は触ってないんですね。実際ちゃんとするにはクリッピングとか考えないと行けません。
GDIのクリッピングを使うのも一つ手ですけどね。
「指定範囲のクリッピング」
http://wisdom.sakura.ne.jp/system/winap ... in134.html

それと、私のリファクタリングよりも共通化や関数化が少ない気がしますがご本人にとって分かりやすくなったのでしょうか?
あとなぜC++の参照とかを使わなかったり、構造体配列を使わなかったり、POINT構造体があるのに使わなかったりするのでしょうか?
MFCに変えるとしてもC++を使いこなさないと厳しいですし、よりリファクタリングがややこしくなります。
私は日頃MFCなので、Win32APIよりも答えやすいことは確かですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#29

投稿記事 by KEYONN_ » 12年前

このソースだと、再生するアルゴリズムはいくつかやり方はあると思いますが、
とりあえず、vPosを加算して、StartY<0かつ、EndY>0なら再生にしたいと思います

もしくは、エディットボックスか、リストボックスにデータを書き込み、その文字列を読んで、
再生するのも考えられます。
(この場合、同時とか、少しずれて再生される場合、時間の管理が肝となる気がします)

どちらが、お勧めでしょうか?

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#30

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:別にMFCは逃げではないと思いますが同じぐらい苦労すると思います。MFCの実体はWin32APIですからね。作っていると色々とAPIの姿が見え隠れします。
ちなみにVB6よりも今時のVB.NETの方が速度的には早くなっています。
どっちしろ、長いプログラムを組むためにはリファクタリングやらマメな関数化とかやらなければいけないことは沢山あります。
MFCの方が難しいのですね。
softya(ソフト屋) さんが書きました:新しいのを見ましたが、結局画像の描画領域の問題は触ってないんですね。実際ちゃんとするにはクリッピングとか考えないと行けません。
GDIのクリッピングを使うのも一つ手ですけどね。
「指定範囲のクリッピング」
http://wisdom.sakura.ne.jp/system/winap ... in134.html
クリッピングやってみました。
でも、うまくいかず、結局直接プログラミングでif文をつかい、クリッピングしました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#31

投稿記事 by softya(ソフト屋) » 12年前

KEYONN_ さんが書きました:このソースだと、再生するアルゴリズムはいくつかやり方はあると思いますが、
とりあえず、vPosを加算して、StartY<0かつ、EndY>0なら再生にしたいと思います

もしくは、エディットボックスか、リストボックスにデータを書き込み、その文字列を読んで、
再生するのも考えられます。
(この場合、同時とか、少しずれて再生される場合、時間の管理が肝となる気がします)

どちらが、お勧めでしょうか?
表示ではなく再生の話ですよね?
class Noteのインスタンスに格納された値を使えば良いのでは?
表示と再生のために情報を蓄えているんだと思っていました。
ただし、今の蓄え方は時間軸でのソート向きではありません。
list構造にするとかSTLのlistを使うほうが良いでしょう。

プログラム全体的にそうなのですが音階や時間情報なのか座標情報なのか持つ情報が論理的に整理されていません。どちらも持っているというか結構アバウトです。
鍵盤画像のサイズが変わったら困るでしょうし、縦のスクロール全体のサイズを変えるときに面倒ではありませんか?
それにファイル書き出しの場合を考えて、内部でのデータの持ち方を標準midiファイル(smf)に出来だけ近い形にしたおいたほうが後々楽だと思います。

再生時はclass Noteの情報で音を再生して表示はそれに合わせればよいだけです。
そこら辺はデータインターフェイスを設計しましょう。
私としてはclass Noteの情報は音階や時間の情報だけでよく、座標は変換関数で変換すれば良いようにすべきだと思います。
そうすれば、標準midiファイル(smf)のファイルも読み込めますからね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#32

投稿記事 by softya(ソフト屋) » 12年前

KEYONN_ さんが書きました:
softya(ソフト屋) さんが書きました:別にMFCは逃げではないと思いますが同じぐらい苦労すると思います。MFCの実体はWin32APIですからね。作っていると色々とAPIの姿が見え隠れします。
ちなみにVB6よりも今時のVB.NETの方が速度的には早くなっています。
どっちしろ、長いプログラムを組むためにはリファクタリングやらマメな関数化とかやらなければいけないことは沢山あります。
MFCの方が難しいのですね。
私はMFCの方が作りやすいです。
でも、オブジェクト指向をそれなりに理解している必要があると思います。
KEYONN_ さんが書きました:
softya(ソフト屋) さんが書きました:新しいのを見ましたが、結局画像の描画領域の問題は触ってないんですね。実際ちゃんとするにはクリッピングとか考えないと行けません。
GDIのクリッピングを使うのも一つ手ですけどね。
「指定範囲のクリッピング」
http://wisdom.sakura.ne.jp/system/winap ... in134.html
クリッピングやってみました。
でも、うまくいかず、結局直接プログラミングでif文をつかい、クリッピングしました。
うまく行っているのなら良いですが、スクロールバーを左にスライドさせた場合Pic2の右側にゴミが出る問題は直ったのでしょか?

[追記]
これにもお答えいただけますか?
それと、私のリファクタリングよりも共通化や関数化が少ない気がしますがご本人にとって分かりやすくなったのでしょうか?
あとなぜC++の参照とかを使わなかったり、構造体配列を使わなかったり、POINT構造体があるのに使わなかったりするのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#33

投稿記事 by KEYONN_ » 12年前

>>うまく行っているのなら良いですが、
>>スクロールバーを左にスライドさせた場合Pic2の右側に
>>ゴミが出る問題は直ったのでしょか?
直りました。
softya(ソフト屋) さんが書きました: [追記]
これにもお答えいただけますか?
それと、私のリファクタリングよりも共通化や関数化が少ない気がしますがご本人にとって分かりやすくなったのでしょうか?
あとなぜC++の参照とかを使わなかったり、構造体配列を使わなかったり、POINT構造体があるのに使わなかったりするのでしょうか?
分かりやすくなったといえば、なりましたが、ソフト屋さんのソースよりか
は分かりにくいです。
あと、C++の参照を使わなかったのと、POINT構造体を使わなかったのは、
ソフト屋さんのソースと違い、オリジナリティを出したかったからです。
でも、よく考えてみると、便利なものを使わないソースは勿体無いですね。

構造体配列を使わなかったのは、MOUSE構造体に、配列を使う利点が思いつかなかったからです。あと、構造体というのは、MOUSE構造体で合ってますか?
構造体はクラスの一種ですが、クラスのNOTEクラスの事を指しているとしたら、
それは、クラスの配列は、コンパイル時に警告が出るからです。(VisualC++6.0の場合)
VisualC++2008では警告は出ませんでした。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#34

投稿記事 by softya(ソフト屋) » 12年前

描画上手く行っているなら問題ないです。2008とのダイアログのサイズの単位違いの問題かな?
KEYONN_ さんが書きました:構造体配列を使わなかったのは、MOUSE構造体に、配列を使う利点が思いつかなかったからです。あと、構造体というのは、MOUSE構造体で合ってますか?
構造体はクラスの一種ですが、クラスのNOTEクラスの事を指しているとしたら、
それは、クラスの配列は、コンパイル時に警告が出るからです。(VisualC++6.0の場合)
VisualC++2008では警告は出ませんでした。
私の説明が分かり辛ったですね。class Note内のデータを私のように構造体化しないのかって話です。
私の目論見では時間軸でソートする必要性が出て来ると思うので、そういう話を出したってのが正しいです。
たぶん、私が最終的な処理を見越して話をしているのとKEYONN_さんが現状のコードでの話をしているのでズレが生まれるんだと思います。

クラス自体の配列は、今回使わなくても良いと思います。
VC++6.0は持っていないので検証は無理ですごめんなさい。

[追記]
追記しておきます。

コード:

あと、C++の参照を使わなかったのと、POINT構造体を使わなかったのは、
ソフト屋さんのソースと違い、オリジナリティを出したかったからです。
でも、よく考えてみると、便利なものを使わないソースは勿体無いですね。
意味のあるオリジナルティなら良いですが、意味もなく違っているだけに拘ることはあまりよくない事と言えます。
プロフィールにプログラマーを目指していると書かれているので、一般性のある書き方を目指されるべきだと思いますよ。
それと、今のまま書き加えていくことはプログラムが破綻する可能性が高いので、長いプログラム、大きなプログラムに相応しい書き方を意識されるべきでしょう。
私の指摘の大半は、小さなプログラムでも問題ですが、特に大きなプログラムを書いた時に相応しくない点を書いていますので意識してみて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#35

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:描画上手く行っているなら問題ないです。2008とのダイアログのサイズの単位違いの問題かな?
KEYONN_ さんが書きました:構造体配列を使わなかったのは、MOUSE構造体に、配列を使う利点が思いつかなかったからです。あと、構造体というのは、MOUSE構造体で合ってますか?
構造体はクラスの一種ですが、クラスのNOTEクラスの事を指しているとしたら、
それは、クラスの配列は、コンパイル時に警告が出るからです。(VisualC++6.0の場合)
VisualC++2008では警告は出ませんでした。
私の説明が分かり辛ったですね。class Note内のデータを私のように構造体化しないのかって話です。
私の目論見では時間軸でソートする必要性が出て来ると思うので、そういう話を出したってのが正しいです。
たぶん、私が最終的な処理を見越して話をしているのとKEYONN_さんが現状のコードでの話をしているのでズレが生まれるんだと思います。

クラス自体の配列は、今回使わなくても良いと思います。
VC++6.0は持っていないので検証は無理ですごめんなさい。
分かりました。

[追記]
追記しておきます。

コード:

あと、C++の参照を使わなかったのと、POINT構造体を使わなかったのは、
ソフト屋さんのソースと違い、オリジナリティを出したかったからです。
でも、よく考えてみると、便利なものを使わないソースは勿体無いですね。
意味のあるオリジナルティなら良いですが、意味もなく違っているだけに拘ることはあまりよくない事と言えます。
プロフィールにプログラマーを目指していると書かれているので、一般性のある書き方を目指されるべきだと思いますよ。
それと、今のまま書き加えていくことはプログラムが破綻する可能性が高いので、長いプログラム、大きなプログラムに相応しい書き方を意識されるべきでしょう。
私の指摘の大半は、小さなプログラムでも問題ですが、特に大きなプログラムを書いた時に相応しくない点を書いていますので意識してみて下さい。
>>意味のあるオリジナリティなら良いですが、意味も無く違っているだけに拘ることはよくない事
>>と言えます。
はい、そうですね。
プログラマーを目指したいので、一般性のある書き方を目指します。
>>今のまま書き加えていくことはプログラムが破綻する可能性が高いので、長いプログラム、
>>大きなプログラムにふさわしい書き方を意識するべきでしょう。
ちょっと、今までの指摘の数々を見直してみます。
それと、返信遅れてすみませんでした。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#36

投稿記事 by softya(ソフト屋) » 12年前

また色々と書いてしまいましたが、プロを意識されているとの事なので厳しめに書かせて頂きました。

業務で使えるレベルで組むためには、それなりにちゃんと入出力設計やデータ設計を行なってプログラム自体の内部データも一貫性を持った組み方をされている必要があります。
現状のソースコードは座標なのか、時間なのか、音程なのか保存するデータの情報単位に一貫性がありません。
一般的にデータはより抽象化の高い情報として保持していたほうが保守性が高く使い回しが効きますので物理性の高い(抽象性が低い)座標の情報で保持していることは余りよろしく有りません。例えばnoteの値もMIDIMSGの値となっていますが最終的にあの値であれば良いのでもっとスタンダードMIDIに仕様を合わせた抽象化データに出来るのではないかと思うわけです。

上記な理由で最初の方に、とりあえずやっつけで作りたいのか?とお聞きしたわけです。
ただ、途中で自分自身のやっている座標中心の管理で混乱しているように見えたので、より抽象性の高いコードを私が書いてみた訳ですがうまく伝わらなかったようです。

あと気になったこと。
・一部のインデントが適当に成っている。
・あちこちに数値が直接書いてあることもメンテナンス性が低い要因ですので計算で求められることは計算で求めるべきでしょう。数値がひとつも無くなるがベストですが出来るだけ数値で書かれた場所が最小限になる工夫をすべきです。
・構造体の使い方やクラス化が不十分です。特に「int note[MAX_NOTE];//ノート番号」や「int program[MAX_NOTE];//プログラム番号」などの別々の配列にする意味は分かり辛くするだけで関連するデータを1つのまとめるオブジェクト化の指向に反しています。
・STLなどを活用していませんので可変サイズのデータを固定サイズで管理してしまっています。listなどを使えばデータ追加や削除がクラス管理できます。
・MyDlgProcなどが長くなりすぎているので別の関数やクラスに分離しソースのみわたしを配慮しましょう。
「GARAさんのページ」 ← WndProcのクラス化の例。
http://hp.vector.co.jp/authors/VA011804/mfc_c0.htm
・演奏をちゃんと行うためにもスレッド化などを考えましょう。
・[追記]変数名や関数名などちゃんと意図を反映した名前を付けましょう。
ここら辺りまで配慮すればプロに近い書き方に近づけます。
ソースを見ると苦手なことを避けて安易な手法を持ちている様に見受けられますので積極的に挑戦して下さい。

あと仕事としてC++を使えるようにしたかったら出来ればMFCなども覚えるべきですし、最新のVB.NETやC#も考えるべきです。MFCの将来性は不安なので一押しでは無いですが。

「補足」
結局のところ自己流であれこれやっているより未経験可の会社に就職したほうが変な会社に入らない限り早く技術は身につけられます。
自分でアプリを完成させられる技術を確立して就職活動に役立てようとする事はかなり困難な道のりで悪い癖もつきやすいので、より一般性を心がけて高い目標を心がけない限り難しいと私は思います。

下記のサイトなどに目を通して、より一般的な技術を身につけられる事を目指された方が良いでしょう。
「CodeZine:プログラミングに役立つソースコードが満載な開発者のための実装系Webマガジン」
https://codezine.jp/
「開発プロセス:ITpro」
http://itpro.nikkeibp.co.jp/upper/
「ソフト開発:ITpro」
http://itpro.nikkeibp.co.jp/develop/
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#37

投稿記事 by KEYONN_ » 12年前

実は、2年前、ソフトウェア会社の面接で、ソースコード(お絵かきソフト[WIN32API]DibSectionを利用
したもの)を見せたのですが、「C言語をもう一度勉強し直してきなさい」といわれました。
それは、今思えば、汚いソースで、ポインタもろくに分かっていないものでした。

そして面接に落ちたのですが、それ以外にも、理由として、コミュニケーション能力とか、
うまく受け答えできないというのがあったと思います。

僕はプログラマに向いていないんじゃないか?とさえ思えてくるんですが、
実際の所、どうなのでしょうか?

僕は文字でやり取りするのはそんなに不得意じゃないのですが、相手の顔を見ながら、
言葉でやり取りするのは苦手です。
あと、SKYPE用にWEBカメラを買ったのですが、言葉でやり取りしようとすると、
どうしても、考えが頭にわいてきません。

それから、未だに自分の事が見えません。というのは、自分の事に関してですが例えば
「これがこうだから、こうなるんです」と言えません。頭の中が整理されていないのも
ありますが、小さい時からそうでした。知らない相手ならなおさらです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#38

投稿記事 by softya(ソフト屋) » 12年前

【少し補正】
どちらかと言うとみなさんの意見を伺ったほうが良い話題だと思いますが、プログラマー・SEにも色々あるので客先の打ち合わせや対外交渉を専門とする仕事もありますが少なくともチーム内の打ち合わせは必要です。
WEB、ゲーム、業務システム、銀行などの業務オンライン、組み込みマイコン、制御、研究などさまざまな仕事がありますので取り組み方も様々で個人で黙々とやるようなものも少数派ですが無くはありません。ただ、それなりに高い技術力が要求されます。
明日また書き込みますが雑談トピックでいろんな意見を聞いてみたほうが良いと思います。

【追記】
「向いていないんじゃないでしょうか?」と言う質問については自分のやりたい事と出来る事のギャップがあるんじゃやないでしょうか?
そのギャップを埋めるための努力はするしかないですし、思っきりやっていれば自分の限界も見えてきます。
技量の範囲で出来るプログラミングの仕事も探せば有るのではないでしょうか(今の厳しい不況の状況だと保証はできません)。

コミュニケーションに関しては、その人の性格・特性によるのでやれることをやるしか無いです。
焦ると分けがわからなくなるのは仕方ないですが、メモを取るとか状況を整理する工夫は考えてみましょう。

※ 世の中に沢山いるのですが軽度のアスペルガーっぽいかな?と言う印象は持ちました。句読点がやたらと多いのもアスペルガーの特徴です。俗に言われる理系の人ってやつですね。
私も句読点が苦手な軽度アスペルガーの疑いがある人です。そういう脳なんだからと自分を意識してできる事をやっていくのが上手くやるコツではないでしょうか。
[追記の補足] すべてのアスペルガーの人の特徴では無いですが同時処理(並行作業)が苦手な人が多い様です。なので私もマシンガンのようにまくし立てられると頭がホワイトアウトします。
まぁアスペルガーといっても発達障害に分類されるほど強度ではないのでボーダーに属するって事なのですが、健常者⇔アスペルガーの境界は実に曖昧なのです。これも人類の多様性の一部なのでしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#39

投稿記事 by ISLe » 12年前

KEYONN_ さんが書きました:それから、未だに自分の事が見えません。というのは、自分の事に関してですが例えば
「これがこうだから、こうなるんです」と言えません。頭の中が整理されていないのも
ありますが、小さい時からそうでした。知らない相手ならなおさらです。
緊張して頭の中が真っ白になるタイプですか?
頭の中であれこれ考えてしまって次の手に悩んでしまうタイプですか?

コミュニケーションはプログラムに例えると同期処理です。
同期処理が苦手だと構造化や大規模開発にも支障が出ます。

上の質問、前者なら人前に慣れるしか無いのですけど、後者ならいつも考えていることを言葉に出すようにすると良いと思います。
頭の中だけで考えるより時間が掛かるので面倒くさいと感じるでしょうけど、その余裕がコミュニケーションには必要なのです。

わたしも同じような性質なのでプログラマに向いてないということはないと思いたいです。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#40

投稿記事 by KEYONN_ » 12年前

ISLe さんが書きました:
KEYONN_ さんが書きました:それから、未だに自分の事が見えません。というのは、自分の事に関してですが例えば
「これがこうだから、こうなるんです」と言えません。頭の中が整理されていないのも
ありますが、小さい時からそうでした。知らない相手ならなおさらです。
緊張して頭の中が真っ白になるタイプですか?
頭の中であれこれ考えてしまって次の手に悩んでしまうタイプですか?

コミュニケーションはプログラムに例えると同期処理です。
同期処理が苦手だと構造化や大規模開発にも支障が出ます。

上の質問、前者なら人前に慣れるしか無いのですけど、後者ならいつも考えていることを言葉に出すようにすると良いと思います。
頭の中だけで考えるより時間が掛かるので面倒くさいと感じるでしょうけど、その余裕がコミュニケーションには必要なのです。

わたしも同じような性質なのでプログラマに向いてないということはないと思いたいです。
私は、同時に何かをやる事は苦手だと思います。しかし、なんとなくイヤホンで聴きながら、人の話を
することは出来ます。あと、漫画とかを見ている時(没入している時に)話しかけられると、
何を言っているのか理解できない場合があります。
>>後者ならいつも考えていることを言葉に出すようにすると良いと思います。
>>頭の中だけで考えるより時間が掛かるので面倒くさいと感じるでしょうけど、
>>その余裕がコミュニケーションには必要なのです。
アドバイスありがとうございます。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#41

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:【少し補正】
どちらかと言うとみなさんの意見を伺ったほうが良い話題だと思いますが、プログラマー・SEにも色々あるので客先の打ち合わせや対外交渉を専門とする仕事もありますが少なくともチーム内の打ち合わせは必要です。
WEB、ゲーム、業務システム、銀行などの業務オンライン、組み込みマイコン、制御、研究などさまざまな仕事がありますので取り組み方も様々で個人で黙々とやるようなものも少数派ですが無くはありません。ただ、それなりに高い技術力が要求されます。
明日また書き込みますが雑談トピックでいろんな意見を聞いてみたほうが良いと思います。
アドバイスありがとうございます。
softya(ソフト屋) さんが書きました:【追記】
「向いていないんじゃないでしょうか?」と言う質問については自分のやりたい事と出来る事のギャップがあるんじゃやないでしょうか?
そのギャップを埋めるための努力はするしかないですし、思っきりやっていれば自分の限界も見えてきます。
技量の範囲で出来るプログラミングの仕事も探せば有るのではないでしょうか(今の厳しい不況の状況だと保証はできません)。

コミュニケーションに関しては、その人の性格・特性によるのでやれることをやるしか無いです。
焦ると分けがわからなくなるのは仕方ないですが、メモを取るとか状況を整理する工夫は考えてみましょう。
自分のやりたい事と出来る事のギャップがありますね。
そのギャップを埋めるための努力はするしかないですね。
まだ、限界ではないはずです。(少なくとも自分ではそう思っている)

softya(ソフト屋) さんが書きました: ※ 世の中に沢山いるのですが軽度のアスペルガーっぽいかな?と言う印象は持ちました。句読点がやたらと多いのもアスペルガーの特徴です。俗に言われる理系の人ってやつですね。
私も句読点が苦手な軽度アスペルガーの疑いがある人です。そういう脳なんだからと自分を意識してできる事をやっていくのが上手くやるコツではないでしょうか。
[追記の補足] すべてのアスペルガーの人の特徴では無いですが同時処理(並行作業)が苦手な人が多い様です。なので私もマシンガンのようにまくし立てられると頭がホワイトアウトします。
まぁアスペルガーといっても発達障害に分類されるほど強度ではないのでボーダーに属するって事なのですが、健常者⇔アスペルガーの境界は実に曖昧なのです。これも人類の多様性の一部なのでしょう。
平行作業は苦手かもしれないです。
何が平行作業に属するか分かりませんが、没入した状態で声をかけられると、わけがわからなくなります。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#42

投稿記事 by ISLe » 12年前

KEYONN_ さんが書きました:私は、同時に何かをやる事は苦手だと思います。しかし、なんとなくイヤホンで聴きながら、人の話を
することは出来ます。あと、漫画とかを見ている時(没入している時に)話しかけられると、
何を言っているのか理解できない場合があります。
わたしも似たような感じです。
わたしは「ながら」はぜんぜんダメです。
テレビの映像に没入すると音声が聞こえなくなることがあります。
逆に雑音が気になって雑音しか聞こえなくなることもあります。
わたしの場合、何を言ってるか理解できないのではなく、まったく聞こえないんですよね。
むかしは集中してるときに中断させられるとキーッ!ってなってました。いまでもたまにありますけど。

ただ、そのことはコミュニケーションとは関係無いと思います。
わたしはいまでもそんな調子ですが、地域のプログラム勉強会とかに出て発表したり雑談したりはふつうにできてますので。

性質は簡単に変えられるものではないですが、ひとつずつゆっくり考えるクセを付ければ人前でも上手く立ち回れるようになると思いますよ。
それで頭の回転がいつも遅くなってしまうわけではないので安心してください。

そうして状況に合わせたり相手の視点でモノを見たりすることができるようになると、オブジェクト指向プログラミングにも役立つかもしれません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#43

投稿記事 by softya(ソフト屋) » 12年前

まだまだやれると思っていて、不十分な理解状態であると感じているならこの「WINAPI)Midiシーケンサの製作(基本機能のみ)」について言えば不十分な理解、やるべきことを後回しにしてなぜか完成を目標にしている(今やるべきことは挑戦や難しい所の取り組みであって後回しにすることではないはずです)、一般性よりオリジナリティにこだわることが問題だと思います。あと、難しいことは全て後回しているように見受けられます。この状況は、理解や一般性(可読性・デバッグ性)を後回しにしていたツケが溜まっている状態だと思ってください。特にプログラマーの募集に提出する物としては問題点が山積みだと思います。
なぜなら、C言語やC++の理解も不十分で応用力やプログラムを構築する力もまだまだです。一万行もあるプログラムなんて、どう書いたら良いのか想像もできないと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: (WINAPI)Midiシーケンサの製作(基本機能のみ)

#44

投稿記事 by KEYONN_ » 12年前

softya(ソフト屋) さんが書きました:まだまだやれると思っていて、不十分な理解状態であると感じているならこの「WINAPI)Midiシーケンサの製作(基本機能のみ)」について言えば不十分な理解、やるべきことを後回しにしてなぜか完成を目標にしている(今やるべきことは挑戦や難しい所の取り組みであって後回しにすることではないはずです)、一般性よりオリジナリティにこだわることが問題だと思います。あと、難しいことは全て後回しているように見受けられます。この状況は、理解や一般性(可読性・デバッグ性)を後回しにしていたツケが溜まっている状態だと思ってください。特にプログラマーの募集に提出する物としては問題点が山積みだと思います。
なぜなら、C言語やC++の理解も不十分で応用力やプログラムを構築する力もまだまだです。一万行もあるプログラムなんて、どう書いたら良いのか想像もできないと思います。
この文を読んで、やる気を失いかけていた自分に活気が戻りそうです。
今、現在、STLとウィンドウプロシージャーのクラス化に取り組んでいます。
まだまだ、私は勉強不足なんだと痛感しました。
イテレーターって何?状態ですが、なんとか、がんばりたいです。

閉鎖

“C言語何でも質問掲示板” へ戻る