MINIMIZE CPU USAGE IN SCAN LOOP
It recently came to my attention that some LB programmers were avoiding scan loops because they use 100% of the processor. Scan loops are necessary if you use WM_Liberty.dll or almost anything else that uses LB callbacks. Although the 100% usage is true there's a simple way to cure this. An api call to Sleep is all that's needed. The following two programs were tested on a PII 400 that had 27 tasks running in the background along with Liberty BASIC. As the pictures show the program without the Sleep call used 100% of the processor while the program with the sleep call used only 1%. That 1% included all of the other running tasks too.
'-------- 100% nomainwin open "Use all of that cpu" for window as #1 #1 "trapclose [quit]" [loop] scan goto [loop] [quit] close #1: end
'-------- 1% nomainwin open "Minimun cpu uasage" for window as #1 #1 "trapclose [quit]" [loop] scan 'sleep for 50 milliseconds calldll #kernel32,"Sleep",50 as ulong,r as void goto [loop] [quit] close #1: end
API COLOR DIALOG
Liberty BASIC has a perfectly good color dialog built right in. If you need to have something different though, like a color dialog that pops up fully opened, then you need to do a little work and use the common control color dialog. At first it seems like this would be a stright-forward api call but there is a catch or two. The first catch is this dialog does not like LB structures! The dialog will open and display the color you want but when you move the slider or crosshair to select a color it causes LB to crash. A fix for this is to allocate a little memory and copy the LB structure into it, then the dialog can manipulate this memory all it wants to without affecting your program. When the dialog ends the info can be collected and used. The second catch is getting the dialog to open up in the center of the screen. From my own observations the dialog opens with it's upper left corner at the upper left corner of the client area of it's owner window. So from that observation a centering trick evolved. A window_popup of 0 width and height can be used as the dialog's owner and positioned where the dialog's upper left corner should be. The size 450 x 325 for the color dialog is an estimate.
nomainwin 'this struct is just used for padding 'in this snippet. struct custClr,_ x as char struct cc,_ 'CHOOSECOLOR lStructSize as ulong,_ hwndOwner as ulong ,_ hInstance as ulong,_ rgbResult as ulong,_ lpCustColors as struct,_ Flags as ulong,_ lCustData as ulong,_ lpfnHook as ulong,_ lpTemplateName$ as ptr WindowWidth = 0 WindowHeight = 0 UpperLeftX = Int((DisplayWidth - 450) / 2) UpperLeftY = Int((DisplayHeight - 325) / 2) open " " for window_popup as #hWndDlgOwner hWndDlgOwner = hwnd(#hWndDlgOwner) ccSize = len(cc.struct) cc.lStructSize.struct = ccSize cc.hwndOwner.struct = hWndDlgOwner cc.lpCustColors.struct = custClr.struct 'set the initial color for the dialog to open with. cc.rgbResult.struct = 14483455 'RGB(255 255 220) cc.Flags.struct = 1 or 2 'CC_FULLOPEN or CC_RGBINIT 'Allocate memory for a CHOOSECOLOR structure and copy the cc.struct to it. CallDll #kernel32, "GlobalAlloc", _GMEM_FIXED as long, ccSize as ulong, hMem as long CallDll #kernel32, "GlobalLock", hMem as long, pMem as long CallDll #kernel32,"RtlMoveMemory", pMem as long, cc as struct, _ ccSize as long, ret as void 'make the call with the memory pointer as the argument for the structure. calldll #comdlg32, "ChooseColorA", pMem as long, ret as boolean 'The choosecolor dialog has returned the selected color in 'the structure located in memory. To get these values and use them 'just point the cc.struct to the memory location pMem. cc.struct = pMem ret = cc.rgbResult.struct notice strRGB$(ret) close #hWndDlgOwner 'always free the allocated memory. CallDll #kernel32, "GlobalFree", hMem as ulong, ret as long end function strRGB$(intColor) Blue = int(intColor / (256*256)) Green = int((intColor - Blue *256*256) / 256) Red = int(intColor - Blue*256*256 - Green*256) strRGB$ = str$(Red)+" "+str$(Green)+" "+str$(Blue) end function