NO

Author Topic: LVM_INSERTITEM  (Read 3012 times)

Grincheux

  • Guest
LVM_INSERTITEM
« on: July 04, 2021, 04:01:33 AM »

Hello everybody,

The function used to insert the items is in a thread.
The goal is to display images of all files in a folder.
When the function ends I can see all the images.I use LVM_INSERTITEM to insert data into a ListView
LVM_INSERTITEM always returns 0 as index item.
So I use LVM_FINDITEM with lParam set to the lParam item of the LVITEM structure.
LVM_FINDITEM returns -1

I need some help please about this.

Code: [Select]
                     MOV      _LvFind.flags,LVFI_PARAM

                     MOV      RCX,[hLvImageList + RIP]
                     MOV      RDX,RAX
                     XOR      R8D,R8D
                     CALL   ImageList_Add

                     MOV      _Lvi.iImage ,EAX
                     MOV      _ImageInfos.IndexImageList,EAX

                     LEA      RAX,_ImageInfos.szImageFile
                     MOV      _Lvi._mask,LVIF_DI_SETITEM OR LVIF_IMAGE OR LVIF_NORECOMPUTE OR LVIF_PARAM OR LVIF_TEXT
                     MOV      _Lvi.pszText,RAX

                     MOV      EAX,_iRecNo
                     MOV      _Lvi.lParam,RAX

                     LEA      RCX,_ImageInfos.szImageFile
                     CALL   PathFindFileNameA

                     MOV      RCX,[hListView + RIP]
                     MOV      RDX,LVM_INSERTITEM
                     XOR      R8D,R8D
                     LEA      R9,_Lvi
                     MOV      [R9].LVITEM.pszText,RAX
                     CALL   SendMessageA

                     MOV      _Lvi.iItem,EAX

                     MOV      RAX,[_Lvi.lParam]
                     MOV      _LvFind.lParam,RAX

                     MOV      RCX,[hListView + RIP]
                     MOV      RDX,LVM_FINDITEM
                     MOV      R8D,0
                     LEA      R9,_LvFind
                     CALL   SendMessageA

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: LVM_INSERTITEM
« Reply #1 on: July 04, 2021, 12:26:59 PM »
GUI messages should be in the same thread that created the window, if I well remember, when sending message from a different thread you should use PostMessage().
See this link.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Grincheux

  • Guest
Re: LVM_INSERTITEM
« Reply #2 on: July 04, 2021, 01:23:45 PM »
I replaced SendMessage with PostMessage and now LVM_INSERTITEM always returns 1!

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: LVM_INSERTITEM
« Reply #3 on: July 04, 2021, 03:20:44 PM »
Well, it happened that I remembered wrong  ;D
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline John Z

  • Member
  • *
  • Posts: 790
Re: LVM_INSERTITEM
« Reply #4 on: July 04, 2021, 04:12:35 PM »
Not at all sure, but are you setting the iSubItem to 0?   LVM_INSERTITEM can't be used to insert subitems.


John Z

Grincheux

  • Guest
Re: LVM_INSERTITEM
« Reply #5 on: July 04, 2021, 09:12:06 PM »
John the insertion works well.
Frankie, you were right, I saw the link, I don't understand.
I have too many problems with this program and I will remake it.
Works well with 500 images and problems appear witn 5000 images to display.
Perhaps a problem with SQLite (SQL_BUSY)
Now I am making an other analysis including the problems I met.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: LVM_INSERTITEM
« Reply #6 on: July 04, 2021, 09:23:17 PM »
A suggestion that I can give you is to handle whole GUI stuff in the same thread (that is the standard approach).
Other threads will place requests for GUI actions using shared objects (variables, buffers) or interthread communication.  ;)
About the SQLite consider that each SQL will open and modify the whole database file, and this is very slow, unless you explicitly use transactions (see this link).
Use:
Code: [Select]
BEGIN TRANSACTION;
.....   --Many SQLs
COMMIT TRANSATION;
In this case SQLite will prepare all SQLs in memory and commit them in a single file update when encounters the "COMMIT".
In your program prepare and execute the SQL: "BEGIN TRANSACTION;".
Then run all code that executes other SQLs logically grouped, the prepare and execute the SQL "COMMIT TRANSATION;" to update database file.
« Last Edit: July 04, 2021, 09:34:09 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Grincheux

  • Guest
Re: LVM_INSERTITEM
« Reply #7 on: July 04, 2021, 09:25:07 PM »
What I did before but the program is too slow in that case.
Thank You for the idea.

Grincheux

  • Guest
Re: LVM_INSERTITEM
« Reply #8 on: July 04, 2021, 09:30:22 PM »
I have not tried that but if I create the listview in the same thread that the one used for filling it?
I could use SendMessage.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: LVM_INSERTITEM
« Reply #9 on: July 04, 2021, 09:37:47 PM »
I have not tried that but if I create the listview in the same thread that the one used for filling it?
I could use SendMessage.
You can have a bigger problem because the message loop have to be created also in the new thread, and I don't think that this is what you want.
I don't understand why you say that the program is slow. That is the standard way to produce GUI software. Maybe the problem was somewhere else?
I updated my previous message with some info for SQLite.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline John Z

  • Member
  • *
  • Posts: 790
Re: LVM_INSERTITEM
« Reply #10 on: July 05, 2021, 12:38:43 AM »
To improve list view performance for a large number of items have you used LVM_SETITEMCOUNT?
Set to a large number to improve performance. The data structure will not need allocate for every addition.


John Z

Offline algernon_77

  • Member
  • *
  • Posts: 33
Re: LVM_INSERTITEM
« Reply #11 on: July 05, 2021, 07:54:16 AM »
To improve performance, you can also try the following:

Code: [Select]
// right before inserting items into list
SendMessage ( hList, WM_SETREDRAW, FALSE, 0 );

// .. insert a bunch of items into list
...
...

// finished updating the list, tell it that's ok to redraw now
SendMessage ( hList, WM_SETREDRAW, TRUE, 0 );
InvalidateRect ( hList, NULL, TRUE );

What this does is that it basically tells the listview to disable all scrollbar and item position calculations until you've finished adding all entries to it.
It should have a noticeable effect.

Those WM_SETREDRAW messages should be sent in the main thread.
« Last Edit: July 05, 2021, 07:55:48 AM by algernon_77 »

Grincheux

  • Guest
Re: LVM_INSERTITEM
« Reply #12 on: July 05, 2021, 09:30:20 AM »
JohnZ and algernon_77 I will try your devices.
Frankie
Quote
[size=0px]You can have a bigger problem because the message loop have to be created also in the new thread, and I don't think that this is what you want.[/size]
Yes, that's what I had discovered, but too late I already posted my message.
It is like there was a SORT command, the item always is 0 until it is sorted.
Quote
BEGIN TRANSACTION;
I know that a transation is a way to be faster, but you also can change some pragmas to be quicker too.
Code: [Select]
void SQLite3Pragmas(sqlite3 *__hSqlite)
{
   sqlite3_exec(__hSqlite,"PRAGMA wal_autocheckpoint = 0",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA encoding = \"UTF-8\"",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA cache_spill=FALSE;",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA temp_store = MEMORY",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA case_sensitive_like = TRUE",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA foreign_keys = OFF",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA legacy_file_format = OFF",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA cache_size = -2000",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.cache_size = -2000",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.auto_vacuum = NONE",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.journal_mode = OFF",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.secure_delete = OFF",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.synchronous = OFF",0,0,NULL) ;  // This one is very efficient for SPEED
   sqlite3_exec(__hSqlite,"PRAGMA main.locking_mode = EXCLUSIVE",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.user_version = 23072014",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA main.application_id = 24121959",0,0,NULL) ;
   sqlite3_exec(__hSqlite,"PRAGMA shrink_memory",0,0,NULL) ;

   return ;
}
The problem is how to manage SQLITE_BUSY, if SQLITE_BUSY is returned with a transaction that upgrades the database, you can restart the upgrade,
if it is a transaction that inserts records, it is less easy. We have to use something like the following:
Code: [Select]
"INSERT OR IGNORE INTO [Hashes]([Hash],[BaseCrc64],[Crc64],[Password]) VALUES (\"%s\",%llu,%llu,\"%w\")" ;
Thank you JohnZ, Frankie & alger_non77 for your help.



« Last Edit: July 05, 2021, 09:32:59 AM by Grincheux »

Grincheux

  • Guest
Re: LVM_INSERTITEM
« Reply #13 on: July 06, 2021, 06:06:03 PM »

Here is a link on the project (ASM Source code and C Source code) + Binaries
Many problems have been solved (one part with your help)

https://www.mediafire.com/file/pt8i7v2vo6eqers/Display.7z/file

I am thinking about a "rename option" that would use the last sort to rename the files like this: [Folder Name]-[0000-nnnn].jpg
but for the instant I must correct bugs and improve the source code, remove dead code...

To install the program just copy it into a folder of your choice, once launched the program creates 2 folders (Datas and Settings).
You must copy the 3 DLLs too : libgfle340.dll + libgfl340.dll + sqlite3.dll

Thank You I have appreciated your help : JohnZ, Frankie and algernon_77
« Last Edit: July 07, 2021, 03:17:38 AM by Grincheux »

Offline John Z

  • Member
  • *
  • Posts: 790
Re: LVM_INSERTITEM
« Reply #14 on: July 07, 2021, 04:17:45 PM »
Adventurously, I'll give it a go.  :)

Thank you for sharing it.

John Z