can someone give me examples how to make group box, radio button, and check box? I have difficulties to make this work. I do everything as it should be, but I can't see the resoult in the application.
Well, if you use an IDE like WinAsm or RadAsm, you can drop controls visually, no need to write the resource code yourself.
Then, these resource scripts are compiled by your resource compiler and they are linked into your application executable image.
You then access these controls using their Identifier (ID) and using the proper complex API.
It's not easy, it's going to take you a while before you are good with GUI. Be prepared for it.
Have you checked the MASM32 examples...
There's iczelion too, Test Department and many other source codes you can find.
upload a small but complete example of a program where it is not working, and someone will happily show you what is wrong.
..... unless it is a password generator for cracking
here it is: Download program.zip (http://host-a.net/nrdev/program.zip)
The GroupBox is not working. :(
I have never used that approach to create dialog boxes because I cannot see what is going on and can't live that way. One thing is obvious to me though. A Group box is used To associate several controls with each other and that is all. You appear to be treating a GroupBox like a Text or Static box. You should create a text box instead. You can then use
WS_TABGRP to associate any of the controls you want to be in the same tab group. Are you trying to show the result there?
Paul
I solved this problem all I needed to is to declare Group Box, radio button, and checkbox, before any ither button.
Yeah, glad you got it fixed. The code for what would be in the group was not included so made troubleshooting a bit of a problem. Always make the controls and then make the group. The z-order is very important here. If you need any more help just ask.
As I said, in memory dialogs are not a favorite of mine. You are undoubtedly attempting to do this job without using a resource script (which is an easy way of doing this). I do the same at times but I use CreteWindowsEx to create all the controls. Download my Sudoku project and see how I created over a hundred controls without using scripting OR an in-memory dialog.
Paul
how can I make a group of objects that will not affect selecting of the other objects?
Example:
Group Box with 5 radio buttons, and Group Box with 2 radio buttons. When user selects one radio button from the first group, and then selects one of the radio buttons from second Group Box, bot options remain selected.
Perhaps a little sample with two groupbox will help you.
Anyway ,try to give a different parent window (the groupbox) to the buttons and perhaps this will anwer your question.
If it not work,try something else.
a group is from one WS_GROUP to the next WS_GROUP.
When you create a window (eg. a button), put WS_GROUP in the dwStyle parameter of the first window (and only the first window) in the group. Every window you create afterward (more buttons or whatever) is in the same group. To start a new group, put WS_GROUP on a new window. It would be nice if there was a StopGroup parameter, but I don't do this enough to know the fine details.
QuoteThe code for what would be in the group was not included
it isn't included because THIS PROGRAM YOU GUYS ARE HELPING WITH IS A PASSWORD GENERATOR
solved the first element in the group box need to have WS_GROUP, and the all other in the group should have WS_TABSTOP.
And this IS NOT a password generator, and is not one of the crack programs or such.
Wait to see the completed program, I should complete this program in few days.
I played with your program (I've never done imdialogs before) and came up with this that works-
Dialog "Serial Number Creator","MS Sans Serif",10, \ ; caption,font,pointsize
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \ ; style
11, \ ; control count
50,50,256,256, \ ; x y co-ordinates
1024 ; memory buffer size
DlgButton "Generate",WS_TABSTOP,75,225,35,11,IDOK
DlgButton "Exit",WS_TABSTOP,115,225,35,11,IDCANCEL
DlgButton "About",WS_TABSTOP,155,225,35,11,100
;DlgProgress PBS_SMOOTH or WS_BORDER,3,210,247,10,102
DlgGroup "Number of combinations",3,5,150,50,201
DlgRadio "option 1",WS_GROUP,10,15,50,10,202
DlgRadio "option 2",0, 10,25,50,10,203
DlgRadio "option 3",0, 10,35,50,10,204
DlgGroup "Second Group", 3,55,150,50,301
DlgRadio "option 1",WS_GROUP,10,65, 50,10,302
DlgRadio "option 2",0, 10,75, 50,10,303
DlgRadio "option 3",0, 10,85, 50,10,304
For some reason I haven't figured out yet, your progress bar makes it crash, so I commented it out here.
thanks I did it in some similar way, but it wont crash.
Can someone tell me how can I create an array of numbers from 0 to 9.
What kind of numbers? ASCII? Literal? Bytes? Words? DWORDs? QWORDs? Floating-point?
.data
nMyArray dd 0,1,2,3,4,5,6,7,8,9
Access the value by some index n:
mov eax,[nMyArray+n*4]
http://www.masm32.com/board/index.php?topic=8286.0
The idea of thee array is this: I need two arrays one for the numbers from 0 to 9, adn one for asci characters from a to z. From witch program should random pick numbers and letters. But I don't know how to do that.
Question: What is the purpose of this program you want to create?
It looks like a password generator to me. Helps a user create a secure password to use.
Or possible a serial number generator?
.data
mychrs db "0123456789abcdefghijklmnopqrstuvwxyz",0
.code
.
.
.
invoke nrandom,35 ; this is a routine in m32lib, fil=nrand.asm
mov cl,byte ptr mychrs[eax] ; random character no in cl.
edit: looks like it has to be 36. Here's my actual test code that works-
.data
mychrs db "0123456789abcdefghijklmnopqrstuvwxyzX",0
newpass db 200 dup (0)
.code
mov esi,199
lea edi,newpass
.repeat
invoke nrandom,36 ; this is a routine in m32lib, fil=nrand.asm
mov cl,byte ptr mychrs[eax] ; random character no in cl.
mov [edi],cl
inc edi
dec esi
.until zero?
invoke MessageBox,0,addr newpass,0,0
ret
By the way, your original test program posted above has an error-
.code
GLOBAL Btn1 dd ?
GLOBAL Btn2 dd ?
GLOBAL Btn3 dd ?
GLOBAL Group1 dd ?
GLOBAL Group2 dd ?
GLOBAL Group3 dd ?
GLOBAL hProgress dd ?
GLOBAL hInstance dd ?
GLOBAL hIcon dd ?
invoke InitCommonControls
mov hInstance, FUNC(GetModuleHandle,NULL)
call main
invoke ExitProcess,eax
; -------------------------------------------------------------------------
start:
main proc
LOCAL lpArgs:DWORD
You started .code before some data statements. The code before the start: will never be executed. It only works because the program starts running at the start: label and falls right into main.
you'll spend more time making a good random number generator - lol
for simple tasks, you can use some low-order bits from QueryPerformanceCounter
as for the arrays, you don't neccessarily need to have them
just write a rountine that spits out random ASCII chars in eax or al
RChar PROC
sub esp,8
RChar0: INVOKE Sleep,1
INVOKE QueryPerformanceCounter,esp
mov eax,[esp]
and eax,7Fh
or al,20h
cmp al,'0'
jb RChar0
cmp al,'9'
jbe RChar1
cmp al,'a'
jb RChar0
cmp al,'z'
ja RChar0
RChar1: add esp,8
ret
RChar ENDP
something like that should work
EDIT - i mentioned this program to Hutch - he seems ok with it
EDIT - there are better ways to do it - you could force all values from the performance counter to be valid
with a little manipulation - would be a much better routine - and you could then take out the sleeper
I have made this program before but in basic, it didn't used any letters. If this program looks suspicious to someone it is not some illegal program. The pourpose of this program is to serve as a support utillity for creation serial numbers for protection from piracy. It should generate random combination of the letters and numbers so it can be used to protect any software. You know the thing when you need to type-in the registration code for continuing of installation, or to register some product from shareware to full version, and such.
Maybe it isn't some protection software but it's mine.
There are many reversing/cracking/security forums out there, by the way. Just google and you will find many. Ask questions there if this forum is too restrictive for you. Most of those people will know assembler well anyways...
dedndave,
I think
INVOKE QueryPerformanceCounter,esp
should be
INVOKE QueryPerformanceCounter,esi
Paul
lol - thanks Paul
actually we were both half-right
i have the output going to the stack (scratch-pad)
the bad guy was: mov eax,[esi] sh be: mov eax,[esp]
I know, I had to take a guess which was wrong.
Paul
Jimg have posted the right thing, but that code can't generate truly random numbers. I'am a bit confused I find randlib, that maybe can help me on this. But I doesn't understand what should be a DWORD type. Is it a number or char or what, how can I use that evry function in masm is different and all of the have this?
db 'A',0FFh ;bytes
dw 0FFFFh ;word = 2 bytes
dd 0FFFFFFFFh ;dword (double word) = 2 words
dq 0FFFFFFFFFFFFFFFFh ;qword (quad word) = 4 words
that is way I have asked this question
InitRand PROTO :DWORD,:DWORD
All functions in masm have this format, so how can I use this function
that proto tells you that the function has (2) dword parameters
i don't know where the function InitRand is located, and i see no documentation for it
it is located in randlib.inc and randlibbk.inc
yes - i see the libraries - and the inc's
but i see no docs - no source code
i do see masm32\m32lib\nrand.asm
you might look at that
Quote from: nrdev on May 30, 2009, 11:00:43 AM
Jimg have posted the right thing, but that code can't generate truly random numbers. I'am a bit confused I find randlib, that maybe can help me on this. But I doesn't understand what should be a DWORD type. Is it a number or char or what, how can I use that evry function in masm is different and all of the have this?
What do you mean by this? You don't want the sequence to always start with the same number, or you don't want a repeatable sequence? There are no "truly" random number generators created in code, it takes an uncontrollable physical process, like white noise, radioactive decay, etc. Perhaps the best you can do is use the builtin timer, and do something in between each character that requires windows to do something, some nasty api, garbage collection, access the internet, time the users keystrokes, something that never runs exactly the same amount of time. Then feed this into the seed and get a random number.
i wrote one using the timer (not a great one - lol)
what makes it appear random is that the timer is counting at a very fast rate
the event of the function grabbing a value from it in code (a fairly good pseudo-random event) makes it a good generator
i wrote one for you before - here is a better one.....
;---------------------------------------------------------
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
Randm PROC
;Random ASCII character generator
;generates numbers 0-9 and letters a-z (lower case)
;Call With: Nothing
; Returns: eax = al = pseudo-random ASCII character
INVOKE Sleep,0
sub esp,8
INVOKE QueryPerformanceCounter,esp
pop eax
xor eax,[esp]
add esp,4
xor edx,edx
mov ecx,36
div ecx
xchg eax,edx
add eax,30h
cmp eax,39h
jbe Randm0
add eax,27h
Randm0: ret
Randm ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;---------------------------------------------------------
that sucker will spit out random stuff all day
to use it......
call Randm ;get random char in AL
dedndave, how can I see the result of your code, I want it to be shown in the MessageBox.
well - each time you call the "Randm" function, it returns a random character
to test it, make a string that is some specified length (let's say 10 characters long)
mov edi,offset RandomString
mov ecx,10
RTest0: push edi
push ecx
call Randm
pop ecx
pop edi
cld
stosb
loop RTest0
after the loop executes, the "RandomString" will have 10 garbage characters
Dave-
Since your proc has no parameters or locals, there is no reason to use option prologue:none.
In fact, there is good reason not to screw with option prologue unless absolutely necessary, I may already have one established.
Is there a "save the previous option prologue so I can restore it later" command?
I have put it in my code like this
random_chars:
.if letters + 1
szText NSN,"Serial Number Creator"
mov edi,offset RandomString
mov ecx,10
RTest0: push edi
push ecx
call Randm
pop ecx
pop edi
cld
stosb
loop RTest0
ret
.endif
invoke MessageBox,hWin,ADDR RandomString,ADDR NSN,MB_OK
ret
but it returns error: "invalid operand for OFFSET"
thanks Jim - i just wanted to turn off stack frames - i am a n00b to 32-bit world - lol
nrdev - i wrote a little program to test the generator
it runs in console mode - press any key when you have seen enough random chars
[attachment deleted by admin]
nrdev - the invalid operand is the string name - you have to define the data buffer
add this to the data area.......
.data
RandomString db 12 dup(0)
nrdev,
ESI and EDI are special case registers mostly used for string manipulatuion. Because of this you MUST use LEA, so:
mov edi,offset RandomString
should be;
lea edi, RandomString
If you were using EBX;
mov ebx,offset RandomString
would work.
This is always true.
Paul
Also, this is the random number generator I used in Sudoku,
Random PROTO :DWORD
TimerProc PROTO :DWORD, :DWORD, :DWORD, :DWORD
.data
system_time SYSTEMTIME <> ; Used to seed the random number generator
.data?
rseed dd ?
; The following is in various portions of WndProc
; This is in
.if uMsg == WM_CREATE
invoke GetLocalTime, addr system_time ; Ensures the first Game appears to be random
xor eax, eax ; Need a byte value so clear the rest
mov ax, system_time.wMilliseconds ; Get the currnt time (millseconds)
mov rseed, eax ; Store it as the initial seed
invoke SetTimer, hWnd, 200, 50, offset TimerProc ; Randomizes the rest of the Games
; This goes wherever you want
invoke Random, 4999 ; Randomly (sort of) select a Puzzle
; Now
Random proc range:DWORD
;--------------------------------------
mov eax, rseed ; rseed varies according to the timer
mov ecx, 23 ; Multiplier used to inflate that value
mul ecx ; The rest of this stuff just mucks with the result
add eax, 7 ; in such a way that the ssed is
and eax, 0FFFFFFFFh ; returned with a different value
ror eax, 1 ; to prevent sequential Puzzles
xor eax, rseed ; being chosen by this process
mov rseed, eax ; because TimerProc just bumps the seed by one
mov ecx, range ; Largest value allowed
xor edx, edx ; Prepare for the result of the division
div ecx ; Get the Integer portion of the result
mov eax, edx ; Result is returned in EAX
ret
;--------------------------------------
Random endp
TimerProc proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;--------------------------------------
inc rseed ; Pretty basic, I know, but it is good enough
ret
;--------------------------------------
TimerProc endp
for your purposes, you need to set the value used by
invoke Random, 4999
4999 in this casebecause there are 5000 puzzles in each of four levels, to be the maximum value you wish to obtain.
The stuff in TimerProc is pretty basic but works great, you could add further coding here if necessary. rseed is scoped and will just rollover and over, etc. so, for your purposes, you could invoke TimerProc at many portions of your program. No matter what you do, there is always a pattern, unavoildable. You can eliminate this effect to some degree by reading the Mouse position and use that value to further obfuscate rseed. Just an idea. Mous motions are truly random.
Also, you can add WM_TIMER to WndProc and invoke TimerProc from in there to get some continual alterations to the seed.
Paul
hmmmmmm
i use mov esi,offset label and mov edi,offset label all the time
I have used it successfully also. But sometimes for reasons I cannot say, it does NOT work, so I stopped using it in that manner.
Paul
wow - that is new to me - if you run across a case like that, let me know
inquiring minds need to know !! - lol
Quote from: dedndave on May 30, 2009, 06:32:20 PM
hmmmmmm
i use mov esi,offset label and mov edi,offset label all the time
Since offset label is calculated by the assembler and passed as an absolute (with rebasing by the PE loader) there is no other explanation than an assembler bug for any failure of this instruction. The ability to pass a label address to EDI and ESI is inherent in the processor, they are the source and destination registers for string and table functions so they are expected and designed to receive offsets.
Edgar,
I have often felt it is an assembler bug, especially because I cannot consistantly reproduce it. Another thing that I do not think has ever been successfully fixed is .IF blocks. Sometimes strange things happen and certainly, EAX has to be cautiously used in these blocks. For this reason, I tend to avoid .IF blocks although I still use them. Earlier in my career, I could not afford the debugging time and did not use them at all. Nowadays, I am cautious.
The way my mind works is that a solution or algo gels in my brain over a period of time as I think about what I want to do. Once it gels, I have a window of oppotunity to get those thoughts into typed code. Once the gel point is reached, I type at a furious pace and do not have time to fool with stuff that can be problematic. So I avoid these type of things. There are others that are not at the fore in my mind at the moment but my mind knows what they are and avoids them automatically. Because of this regimen, believe it or not, I generate code that needs very little debugging to the point that I have hardly ever used Olly.
Programming for years was how I put food on the table so I became very rigid in how I do it. There are many bugs in masm as I have discovered over the years but there is not many examples that I could give you. You probably know more of them than I do; but, I would be willing to bet any amount of money that if you were to tell me a scenario that would produce a bug in the assembler; it would be a scenario that I NEVER use.
I could not help but notice that Jeremy does not use .IF blocks in his assembler. I feer he is smart... Why invite trouble.
Paul
dave,
I have been playing because I am a determined sort of guy and I have an interesting report to make and it ALWAYS fails.
CountDlgProc PROC hWind:HWND, uMsg:DWORD, wParam:WPARAM, lParam:LPARAM
;---------------------------------------
LOCAL Count[9]:BYTE
.if uMsg == WM_INITDIALOG
Invoke SendMessage, hWind, WM_SETICON, 1, hIcon ; Display an icon
lea edi, ShowString ; List of current cell values (in ASCII)
lea esi, Count ; < -- This always works
mov ebx, offset Count ; Line 5472 (always fails)
mov esi, offset Count ; Line 5473 (always fails)
Produces:
Quote
Sudoku.asm(5472) : error A2098: invalid operand for OFFSET
Sudoku.asm(5473) : error A2098: invalid operand for OFFSET
Interesting? Whether or not it always pertains to LOCAL variables remains to be seen. All I know is I will stick with what ALWAYS works.
Paul
that is becuase the local variable does not have a fixed location (per
se) in memory - or at least, not that the assembler can recognize
local variables are on the stack and are referenced by something like "[ebp+4]", for example
offset won't work with that one
EDIT - in fact, this is why i turn off prologue/epilogue
if i want a stack frame, i will code it the old fashioned way
i have a hard enough time keeping the stack balanced without the assembler trying to do it for me
i am old enough that the mind is not as sharp as it used to be, but i can still write a stack frame - lol
Quote from: dedndave on May 31, 2009, 03:31:37 AM
local variables are on the stack and are referenced by something like "[ebp+4]", for example
offset won't work with that one
You may have stumbled over that error message "register value overwritten by INVOKE". The snippet below explains why - eax is needed for a
lea of a local buffer.
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32:", 0
AppMsg db "Test", 0
start: call MyProc
exit
MyProc proc
LOCAL buffer[100]:BYTE
invoke lstrcpy, addr buffer, offset AppName
; error A2133:register value overwritten by INVOKE
; xor eax, eax
; invoke MessageBox, eax, offset AppMsg, addr buffer, MB_OK
invoke MessageBox, 0, offset AppMsg, addr buffer, MB_OK
;00401030 ? 8D45 9C lea eax, [ebp-64] <<<<<<<<< 3 bytes
;00401033 ? 50 push eax
;00401034 ? 68 08104000 push 00401008
;00401039 ? 6A 00 push 0
;0040103B . E8 02000000 call <jmp.&user32.MessageBoxA>
ret
MyProc endp
end start
Same but with LOCAL buffer[1
30]:BYTE
00401034 ? 6A 00 push 0
00401036 . 8D85 7EFFFFFF lea eax, [ebp-82] <<<<<<<< 6 bytes
JJ,
Sure have! Something else I avoid like the plague.
Dave,
It should be an error on the first pass but by the second pass addresses are resolved and it should work IMO. Anyway, it does not matter; it don't work so I avoid it in all cases that way (i am old, also) I do not have to think about it. Conditional jumps have this pratfall, also, but the assembler just waits for the second pass, should be the same for this also, both are rsoving an address.
In the old days, I NEVER used stack frames. In fact, I dislike them and feel that people do not learn about stack maintenance because of them. I use a stack frame now because others will use my code at times. I, also used obfuscation all the time which I never do any more, for the same reason.
... and, whatever the reason, I DID produce the error.
Paul
well - i use stack frames occasionally
i certainly use them for recursive routines
but - generally - a direct address to a data define is a better solution
i sometimes use frames as a quick scratch-pad, where speed is not important