Hi Guys, I would like to know your opinions please,
I want to do a loop which will check if a file exists, for example, doing a timer call-back function , Create a thread and use Sleep ( to avoid the increase of the CPU ). opinions? please, thanks! :biggrin:
No extra thread needed, just use SetTimer wisely. Here is a little test - performance depends strongly on whether you use Sleep 1 or Sleep 0...
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
xor ebx, ebx
MsgBox 0, "Open Task Manager and watch the CPU usage. Press Shift to start the second test", "Hi", MB_OK
NanoTimer()
.Repeat
invoke Sleep, 1
.if !Exist("\Masm32\include\Windows.inc")
MsgBox 0, "No WinInc", "Hi", MB_OK
.endif
invoke GetKeyState, VK_SHIFT
inc ebx
.Until ebx>100000 || sword ptr ax<0
MsgBox 0, Cat$(Str$("Sleep 1: %i tests took ", ebx)+Str$("%i ms", NanoTimer(ms))), "Hi", MB_OK
xor ebx, ebx
NanoTimer()
.Repeat
invoke Sleep, 0
.if !Exist("\Masm32\include\Windows.inc")
MsgBox 0, "No WinInc", "Hi", MB_OK
.endif
invoke GetKeyState, VK_SHIFT
inc ebx
.Until ebx>100000 || sword ptr ax<0
MsgBox 0, Cat$(Str$("Sleep 0: %i tests took ", ebx)+Str$("%i ms", NanoTimer(ms))), "Hi", MB_OK
Exit
end start
Sleep or SleepEx is not the right function to use here, a timer in the message loop (WndProc) is more efficient and does not lock the thread for the sleep duration.
Quote from: hutch-- on November 15, 2012, 10:22:31 PM
Sleep or SleepEx is not the right function to use here, a timer in the message loop (WndProc) is more efficient and does not lock the thread for the sleep duration.
Of course. I chose a console example to avoid posting a full-fledged win app, but the logic is the same:
SetTimer handle, ID,
0, 0 is a lot different from
SetTimer handle, ID,
1, 0
depending on what you are doing, you can use FindFirstFile/FindNextFile/FindClose
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364413%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364413%28v=vs.85%29.aspx)
you can use FindFirstFileEx/FindNextFile/FindClose to specify certain attributes
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364419%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364419%28v=vs.85%29.aspx)
in some cases, you can use GetFileAttributesEx, instead - depends on what you're after
works great if you are looking for one specific file
it can be used to tell you if the file exists, attributes, and size
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946%28v=vs.85%29.aspx)
i try to use the later if possible, as it is fast and efficient
if it won't do the job, however, you can use one of the other methods :P
You can also try the shlwapi commands...
PathFileExists() (http://msdn.microsoft.com/en-us/library/windows/desktop/bb773584(v=vs.85).aspx) to discover if a single file or folder exists (no wildcards).
PathIsDirectory() (http://msdn.microsoft.com/en-us/library/windows/desktop/bb773621(v=vs.85).aspx) to discover if a patname is a directory (again no wildcards).
and
PathIsDirectoryEmpty() (http://msdn.microsoft.com/en-us/library/windows/desktop/bb773623(v=vs.85).aspx) to discover if a folder has files in it or not (still no wildcards)
There's a whole mess of these... listed HERE (http://msdn.microsoft.com/en-us/library/windows/desktop/bb773559(v=vs.85).aspx) .
I find them very handy when you're just doing quick checks.
Quote from: CommonTater on November 16, 2012, 03:42:18 AM
There's a whole mess of these... listed HERE (http://msdn.microsoft.com/en-us/library/windows/desktop/bb773559(v=vs.85).aspx).
Hi Tater,
For an assembly coder, there are some highlights on that page ;-)
QuotePathAddBackslash
Adds a backslash to the end of a string to create the correct syntax for a path. If the source path already has a trailing backslash, no backslash will be added.
Note Misuse of this function can lead to a buffer overrun. We recommend the use of the safer PathCchAddBackslash or PathCchAddBackslashEx function in its place.
Thanks guys Really I appreciate your help! :biggrin:
ADD: guys, a question, How to could I to implement to SetTimerProc? any idea please.
Quote from: RHL on November 16, 2012, 05:13:54 AM
How to could I to implement to SetTimerProc?
Simple and straightforward, just follow the SetTimer documentation. If you post your current proc here, we might comment on it.
Quote from: jj2007 on November 16, 2012, 04:56:32 AM
For an assembly coder, there are some highlights on that page ;-)
:biggrin: Glad I could help.
Quote from: CommonTater on November 16, 2012, 07:20:54 AM
:biggrin: Glad I could help.
Lol. Here is one "highlight":
QuoteHRESULT PathCchAddBackslashEx(
_Inout_ PWSTR pszPath,
_In_ size_t cchPath,
_Out_opt_ PWSTR *ppszEnd,
_Out_opt_ size_t *pcchRemaining
);
pszPath [in, out]
A pointer to the path string. When this function returns successfully, the buffer contains the string with the appended backslash. This value should not be NULL.
[Mom, why should the pointer not be NULL?]
Then the final sentence that explains it all:
Minimum supported client Windows 8Win8 users, prepare for the worst :greensml:
Quote from: jj2007 on November 16, 2012, 07:49:36 AM
[Mom, why should the pointer not be NULL?]
The input path can't be NULL because it's going to search for the zero (null) at the end of the string then add a backslash and new null on the end... That would amount to an access violation at address 0.
The PathAddBackslash function is functionally equivalent to...
if (szString[strlen(szString) - 1] != '\\')
strcat(szString, "\")
... in fact it probably uses strcat().
FWIW... I'm doing my level best to ignore Windows 8.
;)
include \masm32\include\masm32rt.inc
.data
ThePath db "C:\Masm32\include", 0
.code
start: mov edi, offset ThePath
xor eax, eax
or ecx, -1
repnz scasb
.if byte ptr [edi-1]!="\"
mov byte ptr [edi-1], "\"
stosb
.endif
inkey offset ThePath
exit
end start
hi, here it is my code, it's simple:
.386
.model flat,stdcall
include masm32rt.inc
MyTimer PROTO :HWND,:UINT,:UINT,:DWORD
.data
nmsg db "the file doesn't exist",0
Myfile db "C:\Test.txt",0
msg MSG <>
.code
start:
invoke SetTimer,0,11,8000,MyTimer
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
invoke ExitProcess,0
MyTimer proc hWnd:HWND,uMsg:UINT,idEvent:UINT,dwTime:DWORD
invoke CreateFile,addr Myfile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,hWnd,addr nmsg,addr nmsg,MB_OK
.endif
ret
MyTimer endp
end start
But now my problem is, How to can I pass parameters/information to Timer procedure? My aim is, don't to use global variables lol
wft? yeah if I don't want to use global variables how can I pass information to timer procedure, for example I want to use a string from
my timer procedure but without global variables, my rustic method was this:
put my string in a textbox control, then in the timer procedure get the control handle ( the control ID is constant, so it doesn't matter )
then use sendMessage to get the string from my timerproc without global variable :P but it's very rustic :( so I think it's impossible or
Is there any way to do this? or maybe how to could I implement a timer procedure ( which i can pass information ).
well any idea thanks guys!
Quote from: RHL on November 16, 2012, 06:03:18 PMif I don't want to use global variables how can I pass information to timer procedure, for example I want to use a string from
one way is to associate the data with the window (-handle)
- use WNDCLASSEX.cbWndExtra + Get/SetWindwoLong
- use Get/SetWindowLong with GWL_USERDATA
- use properties (Set/GetProp)
Quote from: qWord on November 16, 2012, 06:19:55 PM
Quote from: RHL on November 16, 2012, 06:03:18 PMif I don't want to use global variables how can I pass information to timer procedure, for example I want to use a string from
one way is to associate the data with the window (-handle)
- use WNDCLASSEX.cbWndExtra + Get/SetWindwoLong
- use Get/SetWindowLong with GWL_USERDATA
- use properties (Set/GetProp)
GWL_USERDATA looks like very interesting, thank you qWord :biggrin: