Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Refreshing A Process List

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Thu Jun 10, 2010 8:52 am    Post subject: Refreshing A Process List Reply with quote

So for two of my recent projects, I have found that having a process list is useful. Having a refreshing process list is even more useful it seems : D

This is my current code for refreshing:

Code:
case WM_TIMER: {
      int            nFound, nLastMatch;
      TCHAR          szPID[8]            = {0};
      TCHAR          szExeFile[MAX_PATH] = {0};
      PROCESSENTRY32 pe32                = {0};
      LVFINDINFO     lvfi                = {0};
      LVITEM         lvi                 = {0};
      HWND           hwndProcessList     = GetDlgItem( hwndDlg, IDC_PROCESSLIST );
      HANDLE         hSnapshot           = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL );
      int            nProcesses          = ListView_GetItemCount( hwndProcessList );
      LPBYTE         arrProcessFlags     = ( LPBYTE )malloc( nProcesses + NEWPROCESSTOLERANCE );

      RtlZeroMemory( arrProcessFlags, nProcesses + NEWPROCESSTOLERANCE );

      lvfi.flags   = LVFI_PARAM;
      lvi.mask     = LVIF_TEXT | LVIF_PARAM;
      lvi.iSubItem = 0;
      lvi.pszText  = ( LPTSTR )&pe32.szExeFile;

      pe32.dwSize = sizeof pe32;
      Process32First( hSnapshot, &pe32 );

      do {
        lvfi.lParam = pe32.th32ProcessID;
        nFound      = ListView_FindItem( hwndProcessList, -1, &lvfi );

        if( nFound != -1 ) {
          nLastMatch = nFound;
          arrProcessFlags[nFound] = 1;
        }
        else {
          MoveMemory( &arrProcessFlags[nLastMatch+2], &arrProcessFlags[nLastMatch+1], nProcesses + NEWPROCESSTOLERANCE - nLastMatch - 2 );
          nLastMatch++;
          arrProcessFlags[nLastMatch] = 1;
          lvi.lParam = pe32.th32ProcessID;
          lvi.iItem  = nLastMatch;
          _ultot_s( pe32.th32ProcessID, szPID, _countof( szPID ), 10 );

          ListView_InsertItem( hwndProcessList, &lvi );
          ListView_SetItemText( hwndProcessList, nLastMatch, 0, ( LPTSTR )&pe32.szExeFile );
          ListView_SetItemText( hwndProcessList, nLastMatch, 1, szPID );
        }
      }
      while( Process32Next( hSnapshot, &pe32 ) );
     
      CloseHandle( hSnapshot );

      nProcesses = ListView_GetItemCount( hwndProcessList );
      for( int i = nProcesses - 1; i >= 0; i-- )
        if( arrProcessFlags[i] == 0 )
          ListView_DeleteItem( hwndProcessList, i );

      free( arrProcessFlags );
      break;
    }


The most obvious way to do refreshing is to simply clear the entire listview and rewrite it however this causes flickering as well as loss of focus of the current item I believe.

What the current method does is to count the number of processes. It then creates a table with that many elements + NEWPROCESSTOLERANCE which is currently defined as 10. What happens then is that we use the old listview and compare it to a new enumeration of processes. The table is initialised to all 0s and then we set each index to 1 depending on whether it's found in the new enumeration. If a process is found which does not have a match, it is inserted into the listview in the relevant place. And the table shifted up one. This means we have enough space for 10 extra processes ( that was what the tolerance was for ). Since this code is all in a timer I doubt 10 new processes are gonna be created in 0.5 second. Oh we also have the problem here if a process dies and another is created with the same PID. I don't check for that but I don't feel it's necessary. The situation is extremely unlikely considering it all has to happen in a 500ms time frame.

Anyway at the end, we find the new number of processes ( in case it's changed ) according to our new listview, and iterate through the table backwards checking for 0s. If we find a 0 we delete that index. The reason we go backwards is so the index doesn't get all screwed up in the case a delete does happen.

Well this method works fine for the time being. It's just a sloppy method IMO. I'm always looking for an 'elegant' method to everything I suppose and was wondering if you guys had any ideas.
Back to top
View user's profile Send private message
Stylo
Grandmaster Cheater Supreme
Reputation: 3

Joined: 16 May 2007
Posts: 1073
Location: Israel

PostPosted: Thu Jun 10, 2010 1:21 pm    Post subject: Reply with quote

That was the exact method i was thinking about but never had the time to implement it.
that is awesome and i still like your coding style. Cool

_________________
Stylo
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5801

PostPosted: Thu Jun 10, 2010 3:11 pm    Post subject: Reply with quote

this is a pretty good article on flicker, might be worth a run over for some ideas.

http://www.catch22.net/tuts/flicker
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Thu Jun 10, 2010 9:04 pm    Post subject: Reply with quote

I'm more into looking at an efficient method than caring about the flickering. The flickering is just a byproduct of using the most inefficient method.

Flickering can be avoided even with that method though. I had thought of that before. That is to create a virtual listview with the new enumeration. Compare that to the current listview. If there are differences then draw those differences. As you can imagine though that would be even more inefficient than the current method.

@Stylo : Thanks that is ugly ugly code though :/ And an even uglier method IMO
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5801

PostPosted: Fri Jun 11, 2010 12:00 am    Post subject: Reply with quote

i think you're severely overthinking this whole efficiency thing.


is this a purely C project?
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Fri Jun 11, 2010 3:40 am    Post subject: Reply with quote

Yeah. Actually it's not even the efficiency I care about. It's like I said.. uhhh you know this method just seems inelegant.. It just sort of bugs me..
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites