و به نظر من بهترین نوع رسم خط بدین شکل
Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub CmdDraw_Click()
Picture1.ScaleMode = 3
Dim i, start As Long
start = GetTickCount
For i = 0 To Picture1.ScaleWidth Step 2
Call Rectangle(Picture1.hdc, i, 0, i + 1, Picture1.ScaleHeight)
Next i
For i = 0 To Picture1.ScaleHeight Step 2
Call Rectangle(Picture1.hdc, 0, i, Picture1.ScaleWidth, i + 1)
Next i
MsgBox GetTickCount - start
Picture1.AutoRedraw = True
End Sub
شما بهترش سراغ داری به ما هم خبر بدین
Drag نوشته است:حالا چرا تفره می ری کدم رو نقد کن !
منتظرم ها
آخه مگه من چقدر می دونم که بخواهم برنامه شما رو نقد هم کنم ولی تا اونجایی که سوادم می رسه چشم :
بنظرم اولش سرعت برنامست که برای اندازه ها یکم بزرگ خیلی طول می کشه
در ضمن کد زیر گاهی منجر به تولید عددی بزرگتر از 60 می شود و برنامه خطا می دهد
کد شما مختصات نقاط گره رو بدست نمی آره
کد پایین رو اضافه نوشتی
وقتی کد مر بوط به گذشت از خطا رو حذف کنیم کلی خطا می گیره از وجود نداشتن اشیا و قبلا لود شدن آنها یکم توضیح بده که چرا ؟
خودم نوشته است:حالا خوبی هاش
کد هاش رو خوب نوشتی مخصوصا کد های یک خطی رو
از توابع جالبی استفاده کردی من این توابع رو نمی دونستم
از رنگ جالبی هم استفاده کردی مشخصه که به ماتریکس علاقه داری !!!!!!!!
spiderman نوشته است:این یه روش دیگه البته زیاد دقیق نیست. ( دقتش کمه! D:) شاید خودتون بتونین یه کاریش بکنین
http://www.spiderman.persiangig.com/VB/Grid2.zip
ولی من هنوز نفهمیدم دقیقا می خوای چیکار کنی؟! شاید اونی که حامد نوشت به کارت بیاد.
خب تو پستهای اول فکر میکنم توضیح دادم ، و به کمک شما دوستان خوب تا حدودی به نتیجه مطلوب رسیدم . و فکر میکنم در این مقطع دیگه مشکلی نداشته باشم .
البته کد شما هم جالب بود. ولی دقیقا باید موس در گره ها قرار بگیره تا مختصات رو برگردونه که البته راهی برای حل این مشکل به ذهنم میرسه!
یعنی بیایم فاصله مختصات موس رو با مرکز تمامی مختصات ها بدست بیارم و هر کدوم از فاصله ها که کوکتر بود اون مختصات رو به عنوان نقطه کلید شده در نظر بگیرم !
نبی
Darg نوشته است:hamed_Arfaee خیله خوب حالا چرا میزنی
این هم از طرف من باور کنید اصلا قصد کل انداختن ندارم
Object ای موضوع
اووو! ممنونم . زحمت کشیدی .
سرعتش هم خوب بود ولی فکر میکنم اگه از همون متد line استفاده کنم بهتر و سریعتر و کم دردسر تر باشه.
esmaeily-hosein نوشته است:تا جایی که من فهمیدم قراره مثلا روی یک خط کلیک بشه
و یک کاری انجام بشه درسته .
اگر به من باشه من این برنامه رو به این شکل مینویسم
[align=left]
Private Sub Form_Activate()
Rem =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
For i = 0 To Picture1.ScaleWidth Step 10
Picture1.Line (i, 0)-(i, Picture1.ScaleHeight), vbBlack
Next i
End Sub
Private Sub Form_Load()
Picture1.ScaleMode = 3
End Sub
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X
:
:
این روش برای اینکه بفهمیم در کدوم گره کلیک شده خوبه ولی دقیق نیست و زمانی که شبکه ها بزرگ هستند و محل کلیک از گره ها دور می باشد و در واقع نباید مختصاتی رو برگرونه چون در واقع روی گره ای کلیک نشده ، در این صورت هم عددی برمیگردونه که اشتباست . همچنین چون از point استفاده شده فکر میکنم اگر زمینه یک تصویر قرار بدیم ، تمامی روش با شکست مواجه بشه (البته مطمئن نیستم)
به هر حال همون روشی که در دو پست قبل گفتم رو بیشتر توضیح میدم .
با روش هایی که ذکر شد مختصات تمامی گره ها مشخص است ، حال مختصات نقطه ای که کاربر کلیک کرده را نیز بدست می آوریم و فاصله اون رو یعنی abs(x-x2) که x نقطه کلیک شده و x2 مختصات مورد بررسی است ، حال یک حد مجاز تعریف میکنیم و چک میکنیم که کدام فواصل از حد مجاز کوچکتر هستند ، هر لحظه که فاصله کوچکتر بود ، آن x2 به عنوان مختصات گره کلیک شده برگردونده میشه ، برای y نیز به همین ترتیب . امیدوارم تونسته باشم منظور رو برسونم . وگرنه که مثال عملی میزارم . البته شاید در مورد شبکه های کوچک و کلیک شدن در آخر شبکه ، کمی سرعت پایین باشه ولی راه دیگه به ذهنم نمیرسه .
تشکر
نبی
esmaeily-hosein نوشته است:و به نظر من بهترین نوع رسم خط بدین شکل
Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
:
:
اما دوست عزیز شما چرا لقمه رو میچرخونید!
همون متد line چه اشکالی داره که شما api رو پیشنهاد میکنید؟!
سرعتش هم چک کردم تفاوتی نداشت .
تازه این تابعی که شما استفاده کردید در زمانی که برای بار دوم استفاده میشه خطوط رو رسم نکرد!!!
پ.ن: لطفا کدهاتون رو در تگ [code] قرار بدید .
نبی
نقد برنامه :
برنامه قشنگي بود ولي اگر نظر من ميخواي تا حرفه اي تر بشه :
1-به نظر من اون شرط از نظر بهينه سازي کد درست نيست
شايد به نظر خودت باعث زيبايي شدن برنامه شده باشد
ولي اگر يه کم فکر کني ميبيني که برنامه ما به زبان ماشين تبديل ميشه
که يک تقسيم معمولي در زبان ماشين در کمترين خط 5 خط ميشود
واي به حال استفاده از مد و سپس مقايسه اون با صفر
که در هر بار نيز تکرار ميشود .
ولي استفاده از 2 for فقط به زبان اسمبلي 6 خط ميشود
تازه کامپايلر معلوم نيست چگونه آنها را اسمبل ميکند و در اين مسير چقدر
کد جديد به آن اضافه ميشود .
1-مشکل بعدي در برنامه الگوريتم آن است .
به قول خودتون load از يک شي copy ميگيره (کمي فکر کن)
يعني يک بار خواندن و يک بار نوشتن .
در صورتي که با متد Line فقط مينويسي .بين اين دو خيلي تفاوت اساسي
هست . و يک مرحله بيشتر .در ضمن بايد يک بار آنها را نيز unload کني .
شايد از Line بهتر هم باشد . ولي Line از copy يک شي خيلي بهتره
3- مشکل بعدي به نظر من اين خط است :
HSC.Value = Int(Rnd * 70) + 2
اسکرول تو max=60 است و آنوقت شما عدد تصادفي تا 70 توليد
کرده ايد من هر چه فکر کردم نفهميدم چرا ؟
اميدوارم در آينده در کارات موفقتر عمل کني.
هدف من فقط دقت بيشتر در ايجاد برنامه ها بود و هيچ قصد ديگري نداشتم.
و در جواب اون دوستمون که گفته بود point دقیق نیست به ما بگید چرا .
(به ما هم بگید یاد بگیرید ربطشم به شبکه های بزرگ و کوچک نفهمیدم )
و آن قسمتی که مختصات کلیک از گره ما دور یک شرط ساده نیاز داره همین .
حالا میخوای رو خط کلیک بشه میخوای مختصات گره رو بدست بیاری من که حسابی گیج شدم .
و اگر پس زمینه عکس باشد تو با یک رنگ خاص خط ها را رسم میکنی که با پس زمینه تفاوت دارد (اصلا منطقیشم همینه ) پس مشکلی پیش نمی آید .
و این روشی که جدیدا پیدا کردی من که نفهمیدم چیه برنامش بنویس
شاید یه کمکی تونستیم بکنیم .
در مورد مشکل api :
اولا هدف من یادگیری روش جدیدی بود .
دوما همه میدونند سرعت دستورات api بدلیل اینکه به زبان ++c نوشته
شده اند از دستورات vb بیشتره .
برای بار دوم رسم نمیشد :
اگر خاصیت autoredraw =true باشد این مشکل بوجود می اید که مشکل قابل بحثی نیست .
نقل قول: نقد برنامه :
دم همگی گرم ولی من این کد رو خیلی سریع نوشتم ایراداتی که گرفتید همه درستند
esmaeily-hosein نوشته است:ولي اگر يه کم فکر کني ميبيني که برنامه ما به زبان ماشين تبديل ميشه
که يک تقسيم معمولي در زبان ماشين در کمترين خط 5 خط ميشود
واي به حال ...
خوب ما الان داریم تو VB کد مینویسیم
فکر می کنم اگر بخواهیم به همچین مسائلی انقدر توجه و وسواس نشون بدیم باید کد نویسی در VB رو برای همیشه فراموش کنیم
اسماعیل حسین- دوست عزیز برخورد این چنینی من یا هر برنامه نویس دیگه ای با VB اجنباب ناپذیره. هر برنامه نویس می آید و امکانات زبان رو در نظر می گیره بعد بسته به توانایی های اون زبان کد نویسی می کنه.
مسئله قشنگی کد نیست. در اون موردی که تذکر دادید باید معلوم می شد که آیا ISum یک عدد زوج است یا فرد و فکر می کنم بهترین حالتش همون فرمول بود و حالا شما به جزء فرمول ISum Mod 2=0 اگر راهکار دیگه مد نظر دارید بگید تا ما هم از این به بعد از اون استفاده کنیم !
در آخر این بخش: اگر فکر می کنید برنامتون باید در بهینه ترین حالت اجرا و کامپایل بشه تا سرعت عالی داشته باشه برید روی دلفی یا سی کار کنید.
esmaeily-hosein نوشته است:به قول خودتون load از يک شي copy ميگيره (کمي فکر کن)
يعني يک بار خواندن و يک بار نوشتن .
در صورتي که با متد Line فقط مينويسي .بين اين دو خيلي تفاوت اساسي
هست . و يک مرحله بيشتر ...
بله یک بار خواندن و یک بار نوشتن. البته بستگی داره چه کسی این کاررو انجام بده (خود VBA یا اینکه رابط API که در پس زمینه کنترل اشیاء VB پنهان شده)
البته خود من هم فکر می کنم دست هایی در کارند که یه مرحله کپی, ایجاد و حذف یک شئ خط رو سریع تر از ترسیم و پاک کردن یک خط به کمک متد Line, انجام میدند (حداقل که تجربه من اینطوری میگه) و تو پرانتز با توجه به اشاره دوستان بگم گه (آمید وارم دستان امریکا تو کار نباشه چون آمرکا هیچ غلتی نمی تونه بکنه و انرژی هسته ای حق مسلم ماست-فردا پس فردا به دلیل فعالیت های سیاسی سایت رو فیلتر می کنند اونوقت بازم بیایید شعار بدید)
نقل قول: HSC.Value = Int(Rnd * 70) + 2
حالا حواسم نبود یه اشتباهی کردم ها. بابا بشر جایز الخطاست.
اصلاح HSC.Value=int(Rnd*59)+2 خوب شد.
hamed_Arfaee نوشته است:وقتی کد مر بوط به گذشت از خطا رو حذف کنیم کلی خطا می گیره از وجود نداشتن اشیا و قبلا لود شدن آنها یکم توضیح بده که چرا ؟
خوب وقی یک شئ وجود داشته باشه و دوباره بخوای ایجادش کنی بایک پیغام Error مطلب به شما گزارش داده میشه
esmaeily-hosein نوشته است:و به نظر من بهترین نوع رسم خط بدین شکل
Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub CmdDraw_Click()
Picture1.ScaleMode = 3 ...
روشت رو فوق العاده می پسندم. چون GDI هم سرعت بسیار بالاتری داره و هم من فکر می کنم قابل اطمینان تره و در کل اگر یاد بگیریم در کارهای جدی برای گرافیک از GDI استفاده کنیم بهتون قول می دم کارتون موفق خواهد بود
(البته اینجا ما میتونیم از متد Line یا حتی شئ Line استفاده کنیم اما برای کارهای گرافیکی دیگر فکر میکنم که بدون GDI کاری از پیش نیره)
esmaeily-hosein نوشته است:Dim newbutton(5) As VB.CommandButton
من که هرکاری کردم نتونستم شئ ایندکس دار با این روش بسازم اگر شما موفق شدی لطف کن کدش رو هم قرار بده ماهم استفاده کنیم
esmaeily-hosein نوشته است:1-به نظر من اون شرط از نظر بهينه سازي کد درست نيست
شايد به نظر خودت باعث زيبايي شدن برنامه شده باشد
ولي اگر يه کم فکر کني ميبيني که برنامه ما به زبان ماشين تبديل ميشه
که يک تقسيم معمولي در زبان ماشين در کمترين خط 5 خط ميشود
واي به حال استفاده از مد و سپس مقايسه اون با صفر
که در هر بار نيز تکرار ميشود .
ولي استفاده از 2 for فقط به زبان اسمبلي 6 خط ميشود
تازه کامپايلر معلوم نيست چگونه آنها را اسمبل ميکند و در اين مسير چقدر
کد جديد به آن اضافه ميشود .
به نظر من شما کمی زیادی مته به خشخاش میزارید ;)
esmaeily-hosein نوشته است:و در جواب اون دوستمون که گفته بود point دقیق نیست به ما بگید چرا .
نه اینکه دقیق نیست ! منظور من در زمانی بود که تصویری در زمینه قرار داد ، که در این صورت ممکن است رنگ خط ترسیم شده با تصویر یکی باشد.
esmaeily-hosein نوشته است:(به ما هم بگید یاد بگیرید ربطشم به شبکه های بزرگ و کوچک نفهمیدم )
منظور من از شبکه های بزرگ زمانی است که فاصله خطوط ترسیمی بسیار کم باشد و طول و عرض فرم نیز بسیار زیاد . خودتان در نظر بگیرید برای مکان یابی گره ، باید هر بار از گوشه فرم تمامی پیکسل ها تا رسیدن به مکان جاری موس پیمایش شود تا نقاطی که به رنگ خطوط شبکه می باشند شمارش شوند. که خیلی زمان بر است . شاید بهترین راه این باشد که مختصات جاری موس به فواصل خطوط شبکه که معلوم می باشد تثسیم شود و حاصل همان می شود. امیدوارم تونسته باشم منظور رو برسونم.
esmaeily-hosein نوشته است:و آن قسمتی که مختصات کلیک از گره ما دور یک شرط ساده نیاز داره همین .
درسته! راهش رو پیدا کردم و حل شد!
esmaeily-hosein نوشته است:حالا میخوای رو خط کلیک بشه میخوای مختصات گره رو بدست بیاری من که حسابی گیج شدم .
در حال حاظر تمام مشکلات به کمک شما و دوستان حل شد! تا مشکل بعد دوباره مزاحم خواهم شد.
esmaeily-hosein نوشته است:و اگر پس زمینه عکس باشد تو با یک رنگ خاص خط ها را رسم میکنی که با پس زمینه تفاوت دارد (اصلا منطقیشم همینه ) پس مشکلی پیش نمی آید .
هیچ تضمینی وجود ندارد که رنگ تصویر زمینه با خطوط ترسیمی یکی نشود!
esmaeily-hosein نوشته است:در مورد مشکل api :
اولا هدف من یادگیری روش جدیدی بود .
دوما همه میدونند سرعت دستورات api بدلیل اینکه به زبان ++c نوشته
شده اند از دستورات vb بیشتره .
این مورد رو ترجیح میدم با سند بهم ثابت بشه! یعنی اگر راهی باشه من این تفاوت سرعت رو لمس کنم ، اون وقت شاید ملاک رو api قرار بدم . گرچه فکر نمیکنم به دردسرش بی ارزه !
esmaeily-hosein نوشته است:برای بار دوم رسم نمیشد :
اگر خاصیت autoredraw =true باشد این مشکل بوجود می اید که مشکل قابل بحثی نیست .
موضوع به نظر ساده میاد. اما من با autoredraw =true امتحان کردم . این بار هیچ خطی ترسیم نشد. اما به محض مینیمم و ماکزیمم کردن فرم خطوط ظاهر شدند. (تنها در مورد api اینگونه بود و متد line مشکلی نداشت!)
باز هم ازتون تشکر میکنم .
نبی
یه مطلب دیگه که شاید بهش برخورد کرده باشید. و جالب باشه .
مواقعی پیش میاد که لازمه یه Label یا هر شیء دیگه چسبیده به موس باشه و مثلا مختصات مکان فعلی موس رو در خودش نگه داره ....
در پیاده کردن همچین ایده ای مشکلی وجود نداره ، اما مشکل از آنجایی آغاز میشه که موس از فرم خارج بشه ! طبعاً چون موس نسبت به فرم، مختصاتی ندارد پس باید اون Label نیز حذف شود و مقداری را نشان ندهد. اما همچنان بر روی فرم طبق آخرین مختصاتی که موس در فرم قرار داشت باقی می ماند.
چه راهی برای تشخیص اینکه موس از فرم (یا Picture) خارج شده است وجود دارد تا Label را Invisible کنیم.
نبی
توابع API هست كه مختصات موس رو ميده بايد كنترل كني تا وقتي توي فرم هست ليبلت نشون داده بشه.