AutoHotkey Community

It is currently May 24th, 2012, 9:44 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 149 posts ]  Go to page Previous  1, 2, 3, 4, 5 ... 10  Next
Author Message
 Post subject:
PostPosted: March 28th, 2007, 1:13 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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/viewtop ... +loadimage

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 28th, 2007, 4:14 pm 
Offline

Joined: December 18th, 2005, 5:40 pm
Posts: 234
Location: Italy - Galatro(RC)
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 - www.romeosa.com


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 28th, 2007, 4:28 pm 
Offline

Joined: December 18th, 2005, 5:40 pm
Posts: 234
Location: Italy - Galatro(RC)
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 - www.romeosa.com


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 28th, 2007, 4:59 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
well.... that is not the good way. Icon will be very distorted. If there are other sizes its best to use them.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 2:32 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
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
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 2:46 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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.

_________________
Image


Last edited by majkinetor on April 4th, 2007, 2:47 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 2:47 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
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
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 2:50 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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.

_________________
Image


Last edited by majkinetor on April 4th, 2007, 2:53 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 2:52 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
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
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 2:56 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 3:01 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
Thanks a lot. Much appreciated. Have fun surfing. I hope your exames were successful.

_________________
Ciao
toralf
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 3:04 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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

_________________
Image


Last edited by majkinetor on April 4th, 2007, 3:24 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 3:20 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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
}

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 6:19 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
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
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2007, 6:35 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 149 posts ]  Go to page Previous  1, 2, 3, 4, 5 ... 10  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group