 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Mar 28, 2007 1:13 pm Post subject: |
|
|
I seek for help if anybody cares:
This is pIcon from the Add function
| Quote: | | pIcon Optional path to the icon for the item; if you set the number, it will be seen as the icon handle. You can use 32x32 icons from resources if you specify :idx after icon path ( shell32.dll:4 ) |
I am seraching a method to extract icons of different size. Currently I am using this function:
MSDN
| Code: | MMenu_getIcon( pPath, pNum=1 ) {
return, DllCall("Shell32\ExtractIconA", "UInt", 0, "Str", pPath, "UInt", pNum)
} |
It seems that this one can extract only large or small icons as defined by the system.
I think that LoadImage API can do it, but didn't manage to use it.
Can anybody help?
THis is in order to be able to extract icons of adequate size for executables. For instance, if you set MMenu icon size to be 24 and you specify icon from the resource it will be 32 and so cutted off.
The related topic on Ask for Help is:
http://www.autohotkey.com/forum/viewtopic.php?t=17392&highlight=resource+loadimage _________________
 |
|
| Back to top |
|
 |
kiu
Joined: 18 Dec 2005 Posts: 229 Location: Italy - Galatro(RC)
|
Posted: Wed Mar 28, 2007 4:14 pm Post subject: |
|
|
What about loading the icon as 32x32 and then modify its size using Image conversions and capturing with GDI+?
Maybe it's possible to do it in this way
Anyway as I have a little more time I'll try to search how to do it with PhiLho's API _________________ ____________________
______________________
kiu |
|
| Back to top |
|
 |
kiu
Joined: 18 Dec 2005 Posts: 229 Location: Italy - Galatro(RC)
|
Posted: Wed Mar 28, 2007 4:28 pm Post subject: |
|
|
I suggested it cause I'm trying to find a way to show menu icons also from image files, but I'm relatively new to DllCall, so... _________________ ____________________
______________________
kiu |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Mar 28, 2007 4:59 pm Post subject: |
|
|
well.... that is not the good way. Icon will be very distorted. If there are other sizes its best to use them. _________________
 |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Wed Apr 04, 2007 2:32 pm Post subject: |
|
|
Hi majkinetor,
I tried your MMenu on a small example for test purposes. I want the menu to show me the number of folders and files in two directories. But since that process takes some time I wanted the user to see the counting with alive update of the menu. But it doesn't seem to work. What am I doing wrong here?
Sometimes the menu doesn't react or is only have displayed.
Could you please advice a solution?
| Code: | #SingleInstance force
#NoEnv
#include includes
#include MMenu.ahk
#include structs.ahk
CoordMode, tooltip, screen
main := MMenu_Create()
prog := MMenu_Create()
docs := MMenu_Create()
MMenu_Add( main, "Move on a item","", "", "d iDoNothing")
MMenu_Add( main, "Programs", "", "", "m" prog)
MMenu_Add( main, "Documents", "", "", "m" docs )
MMenu_Add(prog, "Please wait!", "", "", "d iDoNothing")
MMenu_Add(prog, "Path", "", "", "iDoNothing")
MMenu_Add(prog, "# of folders", "", "", "iDoNothing")
MMenu_Add(prog, "# of files", "", "", "iDoNothing")
MMenu_Add(prog, "Last modified", "", "", "iDoNothing")
MMenu_Add(prog, "Sum file size", "", "", "iDoNothing")
MMenu_Add(prog, "Result", "", "", "b| d iDoNothing")
MMenu_Add(prog, "x", "", "", "iPPath")
MMenu_Add(prog, "x", "", "", "iPFolder")
MMenu_Add(prog, "x", "", "", "iPFiles")
MMenu_Add(prog, "x", "", "", "iPLastMod")
MMenu_Add(prog, "x", "", "", "iPSize")
MMenu_Add(docs, "Please wait!", "", "", "d iDoNothing")
MMenu_Add(docs, "Path", "", "", "iDoNothing")
MMenu_Add(docs, "# of folders", "", "", "iDoNothing")
MMenu_Add(docs, "# of files", "", "", "iDoNothing")
MMenu_Add(docs, "Last modified", "", "", "iDoNothing")
MMenu_Add(docs, "Sum file size", "", "", "iDoNothing")
MMenu_Add(docs, "Result", "", "", "b| d iDoNothing")
MMenu_Add(docs, "x", "", "", "iDPath")
MMenu_Add(docs, "x", "", "", "iDFolder")
MMenu_Add(docs, "x", "", "", "iDFiles")
MMenu_Add(docs, "x", "", "", "iDLastMod")
MMenu_Add(docs, "x", "", "", "iDSize")
MMenu_Show( main, A_SCreenWidth/2-100, A_ScreenHeight/2-100, "OnMMenu", "IOnInit UOnUninit" )
ExitApp
return
OnMMenu:
return
OnUninit:
StopToGatherData := True
MMenu_Set(prog, "PPath", "x")
MMenu_Set(prog, "PFolder", "x")
MMenu_Set(prog, "PFiles", "x")
MMenu_Set(prog, "PLastMod", "x")
MMenu_Set(prog, "PSize", "x")
MMenu_Set(docs, "DPath", "x")
MMenu_Set(docs, "DFolder", "x")
MMenu_Set(docs, "DFiles", "x")
MMenu_Set(docs, "DLastMod", "x")
MMenu_Set(docs, "DSize", "x")
return
OnInit:
If (M_Menu = Prog){
StopToGatherData := False
SetTimer, StartProg, 10
}Else If (M_Menu = Docs){
StopToGatherData := False
SetTimer, StartDocs, 10
}
Return
StartProg:
SetBatchLines, 50ms
SetTimer, StartProg, Off
StartToGatherData("P", A_ProgramFiles)
Return
StartDocs:
SetBatchLines, 50ms
SetTimer, StartDocs, Off
StartToGatherData("D", A_MyDocuments)
Return
StartToGatherData(Type, Path){
global StopToGatherData,prog,docs
Time := A_TickCount
ToolTip, Timer Start
GetDirDate(Type, Path, NumDirs := 0, NumFiles := 0, LastModTime := 10000000000000, Size := 0)
If StopToGatherData
Return
menu := Type = "P" ? "prog" : "docs"
MMenu_Set(%menu%, Type "Path", Path)
MMenu_Set(%menu%, Type "Folder", NumDirs)
MMenu_Set(%menu%, Type "Files", NumFiles)
MMenu_Set(%menu%, Type "LastMod", LastModTime)
MMenu_Set(%menu%, Type "Size", Size)
Time := A_TickCount - Time
Tooltip, Timer Stop %Time% ms
}
GetDirDate(Type, ByRef Path, ByRef NumDirs, ByRef NumFiles, ByRef LastModTime, ByRef Size){
global StopToGatherData,prog,docs
SetBatchLines, 100ms
menu := Type = "P" ? "prog" : "docs"
MMenu_Set(%menu%, Type "Path", Path)
Loop, %Path%\*, 1, 1
{
If A_LoopFileAttrib contains D
{
NumDirs++
If !Mod(NumDirs, 20)
MMenu_Set(%menu%, Type "Folder", NumDirs)
}Else{
NumFiles++
Size += A_LoopFileSize ;in bytes
If !Mod(NumFiles, 100)
MMenu_Set(%menu%, Type "Files", NumFiles)
}
LastModTime := LastModTime > A_LoopFileTimeModified ? LastModTime : A_LoopFileTimeModified
If StopToGatherData
Return
}
FormatTime, LastModTime, %LastModTime%, ShortDate
If (Size > 1024 * 1024 * 1024)
Size := Round(Size / (1024 * 1024 * 1024),3) . " Gb"
Else If (Size > 1024 * 1024)
Size := Round(Size / (1024 * 1024),3) . " Mb"
Else If (Size > 1024)
Size := Round(Size / 1024, 3) . " Kb"
Else If Size = 0
Size .= "empty"
Else If Size = 1
Size .= " byte"
Else
Size .= " bytes"
}
|
Edit: Fixed a small bug _________________ Ciao
toralf  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Apr 04, 2007 2:46 pm Post subject: |
|
|
I was doing something similar and will post it soon.
FolderMenu that I created load arbitrary folder into the menu. If you call menu while it is in building process you can see first item of the menu being the word "---- IN PROGRESS ---- ". It continues to build menu in the background though, so next time you call it, it will show full menu, or again "in progress" with more items.
I think that dynamic adding of menu items can not be done now with real time update, but I really don't know for sure, as i didn't experiment much with this, it seemd like not important. You can change existing items which is demonstrated with time in the test example. One possible quick solution would be to first add all items as separators, like, if you have 100 files in the folder, you add 100 separators. Then you iterate trought menu using ID's and remove "s" option, change the name to the name of the file, change the icon to the icon of the file. Be aware that this introduces some small bug that happens when you first define all items in the menu without icons, then add icons (some trailin title letters will be cut of). For that, you must add at least 1 icon at the beginning. You can add icon to the separator to fix this, put the same handle for all separator icons. The point to note here that separator in MMenu is dynamic, you can turn any item into separator and vice-versa.
I will post here FolderMenu when I update it to use newest MMenu API as I did it after first API version was completed and didn't find time to update it yet. You can use it to show/create menu like this:
| Code: | | FolderMenu("c:\program files", options="") |
Options are there for some things, like wether to include system and hidden files, wether to break the menu after some number of files, if to load icons etc...
If you want to stick with your code, I can check it out latter and see what I can do about it. _________________

Last edited by majkinetor on Wed Apr 04, 2007 2:47 pm; edited 1 time in total |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Wed Apr 04, 2007 2:47 pm Post subject: |
|
|
It seems when there is a timer running (even with SetBatchLines, 100ms) a while longer the menu isn't responding. I tried to start the timer oustide the OnInit function and the same happend. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Apr 04, 2007 2:50 pm Post subject: |
|
|
Using timers with MMenu isn't good idea, I must documente that. I use it only to postpone execution some number of milliseconds, like for Tooltip example.
Always runnig timer will interfere with MMenu handlers. This is actually hack of AHK, provided to me by Chris. You know that script is blocked when AHK menu is shown, and it continues after user closes the menu. In MMenu, it is not blocked but I let the script go using some info Chris told me, so you are able to process handlers. Keep in mind that although MMenu is very entusiasticaly desgined there are still lot of AHK limitations that forbid it to do some things like a charm. This kind of thing can be 100% successifully done only natively, using C. You shouldn't put MMenu in very stresfull situations, like doing bunch of things in the background while it is displayed, using timers, etc.... The other things that prevents to create and delete menus all the time without losing performance will be fixed in next update. _________________

Last edited by majkinetor on Wed Apr 04, 2007 2:53 pm; edited 1 time in total |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Wed Apr 04, 2007 2:52 pm Post subject: |
|
|
From your reply I see that you didn't look at my code. Not a problem.
I thought as well that it might be problematic to add item dynamically. That's why I added them with a "x" and gave them names. And during the counting I change the text of the items. But why isn't this working. It works in GUIs. Is there someting in the code that prevents these updates?
Edit: I didn't use the timer constantly. I only use it to create a new thread. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Apr 04, 2007 2:56 pm Post subject: |
|
|
| toralf wrote: | | From your reply I see that you didn't look at my code. Not a problem. |
| majkinetor wrote: | | If you want to stick with your code, I can check it out latter and see what I can do about it. |
I am very tired now, can't look at any code, I had exame yesterday from 8 - 23, I barely work today, mainly surf around...
| Quote: | | But why isn't this working. It works in GUIs. |
I will let you know when I check it out. _________________
 |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Wed Apr 04, 2007 3:01 pm Post subject: |
|
|
Thanks a lot. Much appreciated. Have fun surfing. I hope your exames were successful. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Apr 04, 2007 3:04 pm Post subject: |
|
|
well, it works here
I see number of files counting
Documents executes in 1 sec and I can barely see it counting, but Program Files executes for minutes and I see counting all the time. The only problematic thing here is that you can't exit Program Files menu while it is counting or use it at all but I guess Thread, NoTimers somewhere in the MMenu code may fix that.
| Quote: | | Thanks a lot. Much appreciated. Have fun surfing. I hope your exames were successful. | They were. It was pretty intensive law shit as I work in ministry institution. Failure was punishable by getting fired.
EDIT:
It has nothing to do with timers. You blocked the script as loop doesn't permit windows messages to run. The same would happen in C code, even worst, gui wouldn't be udpated at all, you are lucky AHK does that on its own from time to time. Even the sleep -1 didn't help at the beginning of the loop. I will see if I can do something for such cases.
Other then that, your menu looks really kewl. I will see what I can do so this beauty works. I think that this is some AHK limitation and that this must be designed differently to workaround that, but I will see more.
I really don't know what blocks the menu. I tried this
| Code: | GetDirDate(Type, ByRef Path, ByRef NumDirs, ByRef NumFiles, ByRef LastModTime, ByRef Size){
global StopToGatherData,prog,docs
Thread, Priority, -2147483648 |
then this
| Code: | Loop, %Path%\*, 1, 1
{
sleep, -1 ; sleep 100, 1000 |
_________________

Last edited by majkinetor on Wed Apr 04, 2007 3:24 pm; edited 3 times in total |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Apr 04, 2007 3:20 pm Post subject: |
|
|
Ok, this is rather inventive way, and it seems it doesn't block the menu
| Code: | DummyTimer:
StartToGatherData("P", A_ProgramFiles, CONTINUE)
return
GetDirDate(Type, ByRef Path, ByRef NumDirs, ByRef NumFiles, ByRef LastModTime, ByRef Size){
global StopToGatherData,prog,docs
menu := Type = "P" ? "prog" : "docs"
MMenu_Set(%menu%, Type "Path", Path)
Loop, %Path%\*, 1, 1
{
if !Mod(A_Index, 50)
{
SetTimer, DummyTimer, 50
return
}
|
The point is to let the loop break at certain number of files to give the script a rest for GUI to update. The Dummy timer should continue the iteration where Mod() exited.
I did put here just call to original function again, from the beginning to see if it works.
I am still confused why sleep, -1 doesn't work, which is the same as ProcessMessages or DoEvents in Delphi, that is dotNet. Or priority.
Maybe Chris can enligthen us
EDIT: This also means that u can't use Loop, but some other form of iteration that allows to be continued, like APIs GetNextFile, GetFirstFile.
Its funny that the sleep -1 mechanism works in "modality scenario"
| Code: | Gui, show....
loop
{
sleep, -1 ; or sleep 200
if !gui_visible
break
} |
_________________
 |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Wed Apr 04, 2007 6:19 pm Post subject: |
|
|
Thanks for the help,
I managed to do it with the extra timer (break loop and start form that position again. Not very nice or effective, but the menu is responding again. If you find a better solution, please let me know. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Apr 04, 2007 6:35 pm Post subject: |
|
|
Good, I am glad.
I hope you are aware its not MMenu problem at all. What you did is typical mistake which is not trivial to fix. Real solution is about splitting GUI and working procedure into 2 threads, and to call working procedure ASYNCRHONIOSLY. The message queue is in non working thread and GUI can respond normaly to messages while procedure is looping something. Procedure after that informs mother thread that it is finished via callbacks. This is not trivial even in dotNet which has very nice thread support. I know lot about this as I had this problem number of times.
As you see, this must be handled by specific design of scripts in AHK, as it doesn't support multithreading ( .... ) (callbacks are not so mandatory). I will try to see why sleep in loop doesn't work, as it would make ideal solution. _________________
 |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|