Author Topic: Mouse pointers  (Read 11836 times)

0 Members and 1 Guest are viewing this topic.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Mouse pointers
« on: June 09, 2018, 09:14:14 am »
Hello. I just wrote a program that reads some CUR format files. This program shows all the cursors you can draw and at the end one new cursor use. (just for this program, be no worries).

Code: QB64: [Select]
  1. 'CUR file reader for read and draw cursor images from /windows/cursors dir. First version.
  2. 'Writed wihtout format knowledge just only on base from https://en.wikipedia.org/wiki/ICO_(file_format)
  3.  
  4.  
  5. 'can you find, how are writed some "unsupported" files?
  6. 'known bug is bad draw Pen big xl.
  7.  
  8. 'writed for fun by Petr
  9.  
  10.  
  11.  
  12. REDIM CursorsList(0) AS STRING
  13. Path$ = ENVIRON$("systemroot") + "\cursors\"
  14. Mask$ = "*.CUR"
  15. MakeCursorsList Path$, Mask$, CursorsList$()
  16.  
  17. Cursor$ = ENVIRON$("systemroot") + "\cursors\aero_arrow.cur"
  18. Img& = LoadCursor&(Cursor$, x, y)
  19.  
  20. PRINT "One cursor is loaded and will be used. This is Cursor loader info screen. Press any key...": SLEEP
  21.  
  22. _DEST my&
  23. CLS , _RGB32(128, 55, 220)
  24. ShowUsableCursors CursorsList$(), my&
  25.  
  26. SCREEN my&
  27.     PCOPY 1, _DISPLAY
  28.     ViewCursor Img&, x, y
  29.     _LIMIT 25
  30.  
  31. SUB ShowUsableCursors (Cursors() AS STRING, ToScreen AS LONG)
  32.     _DEST ToScreen&
  33.     X = 100: y = 100
  34.     FOR L = LBOUND(cursors) TO UBOUND(cursors)
  35.         P$ = ENVIRON$("systemroot") + "\cursors\" + Cursors(L)
  36.         i& = LoadCursor&(P$, a, b)
  37.         _DEST ToScreen&
  38.         IF i& >= 0 THEN GOSUB Unsupported: _CONTINUE
  39.         _PUTIMAGE (X, y), i&, ToScreen&
  40.         _FREEIMAGE i&
  41.         COLOR _RGB32(255, 255, 254), _RGB32(128, 55, 220)
  42.         _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  43.         X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  44.         IF y + 300 > _DESKTOPHEIGHT THEN
  45.             SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  46.             P$ = ""
  47.         END IF
  48.     NEXT L
  49.     _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "New cursor is now used. Press Esc for end.", ToScreen&
  50.     EXIT SUB
  51.  
  52.     Unsupported:
  53.     _PRINTSTRING (X + 20, y + 50), "Not supported", ToScreen&
  54.     _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  55.     X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  56.     IF y + 300 > _DESKTOPHEIGHT THEN
  57.         SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  58.         P$ = ""
  59.     END IF
  60.     RETURN
  61.  
  62. SUB MakeCursorsList (Path AS STRING, Mask AS STRING, ToArray() AS STRING)
  63.     '    IF not win THEN PRINT "Error: MakeCursosList SUB is designed for Windows only.": SLEEP 1: END
  64.     Current$ = _CWD$
  65.     IF _DIREXISTS(Path$) THEN
  66.         CHDIR Path$
  67.         commandd$ = "DIR " + Mask$ + " /B > CursorsList.txt"
  68.         SHELL _HIDE commandd$
  69.         IF _FILEEXISTS("CursorsList.txt") THEN
  70.             CH = FREEFILE
  71.             OPEN "CursorsList.txt" FOR INPUT AS #CH
  72.             DO WHILE NOT EOF(CH)
  73.                 LINE INPUT #CH, crs$
  74.                 REDIM _PRESERVE ToArray(i) AS STRING
  75.                 ToArray$(i) = LEFT$(crs$, 20)
  76.                 i = i + 1
  77.             LOOP
  78.             CLOSE #CH
  79.         ELSE PRINT "Unknown error. File CursorsList.txt not created.": SLEEP 1: END
  80.         END IF
  81.     ELSE
  82.         PRINT "Error (Sub MakeCursorList): Specified path not exists.": SLEEP 1
  83.         EXIT SUB
  84.     END IF
  85.  
  86. SUB ViewCursor (Cursor AS LONG, ReductionX AS _BYTE, ReductionY AS _BYTE)
  87.     _DEST 0
  88.     _PUTIMAGE (_MOUSEX - ReductionX - 6, _MOUSEY - ReductionY), Cursor&, 0
  89.  
  90. FUNCTION LoadCursor& (Cursor AS STRING, XReturned, YReturned)
  91.     'returns: 1: File not exists, 2: Unsupported format, Value < 0 - valid cursor image
  92.     TYPE CUR
  93.         Reserved AS INTEGER '       2 bytes, always 00
  94.         Image_Type AS INTEGER '     1 = ICO format, 2 = CUR format, others are invalid
  95.         Number_images AS INTEGER '  number images in file
  96.     END TYPE
  97.  
  98.     TYPE Structure
  99.         Image_Width AS _UNSIGNED _BYTE
  100.         Image_Height AS _UNSIGNED _BYTE
  101.         Image_Color_Palette AS _UNSIGNED _BYTE
  102.         Reserved AS _UNSIGNED _BYTE 'always zero
  103.         Horizontal AS INTEGER '      In ICO format: Specifies color planes. Should be 0 or 1.
  104.         '                            In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
  105.         Vertical AS INTEGER '        In ICO format: Specifies bits per pixel.
  106.         '                            In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.
  107.         Size_of_image_data AS LONG
  108.         Offset_from_begin AS LONG
  109.     END TYPE
  110.     SCREEN _NEWIMAGE(800, 600, 32)
  111.     CLS
  112.     ERc = 0
  113.     DIM CUR AS CUR, Structure AS Structure
  114.  
  115.     IF _FILEEXISTS(Cursor$) THEN
  116.         CLOSE #1
  117.         OPEN Cursor$ FOR BINARY AS #1
  118.  
  119.  
  120.         GET #1, , CUR
  121.         PRINT "First 2 bytes (always 0):"; CUR.Reserved
  122.         PRINT "Image type (1 = ICO, 2 = CUR):"; CUR.Image_Type
  123.         PRINT "Number images in file:"; CUR.Number_images
  124.  
  125.         re:
  126.         '   _DEST 0
  127.         PRINT "======================================="; R
  128.         PRINT "Position in file:"; SEEK(1)
  129.         GET #1, , Structure
  130.         PRINT "Image width:"; Structure.Image_Width
  131.         PRINT "Image height:"; Structure.Image_Height
  132.         PRINT "Image color palette: (0 = LONG truecolor, 2 = _UNSIGNED _BYTE?)"; Structure.Image_Color_Palette
  133.         PRINT "Reserved (always zero):"; Structure.Reserved
  134.         PRINT "Number image points from left:"; Structure.Horizontal
  135.         PRINT "Number image points from top: "; Structure.Vertical
  136.         PRINT "Size of image data: "; Structure.Size_of_image_data
  137.         PRINT "Start offset: "; Structure.Offset_from_begin
  138.  
  139.         IF LOF(1) < 10000 AND Structure.Image_Color_Palette = 0 THEN LoadCursor& = 2: EXIT FUNCTION 'some CUR files contains record: Structure.Image_Color_Palette = 0 (LONG) but are saved as CASE 2. If is used CASE 2 program, is then cursor view VERY badly. :-/
  140.  
  141.         XReturned = Structure.Horizontal
  142.         YReturned = Structure.Vertical
  143.  
  144.         A$ = SPACE$(Structure.Size_of_image_data)
  145.         GET #1, , A$
  146.         posice = Structure.Offset_from_begin - 1
  147.  
  148.         IF Structure.Image_Width > 1 AND Structure.Image_Height > 1 THEN
  149.             SELECT CASE Structure.Image_Color_Palette '                                In file is writed 0, but it is 4 byte long depth. Interresting...
  150.                 CASE 0
  151.                     posice = Structure.Offset_from_begin - 1
  152.                     LoadCursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 32)
  153.                     _DEST LoadCursor&
  154.                     FOR DrawY = Structure.Image_Height - 1 TO 0 STEP -1
  155.                         FOR DrawX = 0 TO Structure.Image_Width - 1
  156.                             IF ERc THEN EXIT FOR ' some files contains record as 4 bytes, but are 1 byte! (uses 256 colors, but not truecolor as is recorded in head)
  157.                             Bod& = CVL(MID$(A$, posice, 4))
  158.                             posice = posice + 4
  159.                             PSET (DrawX, DrawY), Bod&
  160.                     NEXT DrawX, DrawY
  161.  
  162.                 CASE 2
  163.                     SEEK #1, posice + 50
  164.                     GET #1, , A$
  165.                     LoadCursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 256) ' 2 bit colored. My lovely. :-D
  166.                     _DEST LoadCursor&
  167.                     _CLEARCOLOR 15, LoadCursor&
  168.                     DrawX = 0: DrawY = 1
  169.                     FOR CursorDraw = 1 TO LEN(A$)
  170.                         Bod = ASC(A$, CursorDraw)
  171.                         Bin$ = DECtoBIN$(Bod)
  172.                         FOR drr = 1 TO LEN(Bin$)
  173.                             comand$ = MID$(Bin$, drr, 1)
  174.                             IF comand$ = "1" THEN clr = 0 ELSE clr = 15
  175.                             PSET (DrawX, Structure.Image_Height - DrawY), clr
  176.                             DrawX = DrawX + 1: IF DrawX > Structure.Image_Width - 1 THEN DrawX = 0: DrawY = DrawY + 1
  177.                         NEXT
  178.                     NEXT
  179.             END SELECT
  180.         END IF
  181.     ELSE LoadCursor& = 1: EXIT FUNCTION 'if file not exists
  182.     END IF
  183.     IF Structure.Image_Color_Palette = 0 THEN _SETALPHA 0, _RGB32(0, 0, 0), Cursor&
  184.     CLOSE #1
  185.     _DEST 0
  186.  
  187. FUNCTION DECtoBIN$ (vstup)
  188.     FOR rj = 7 TO 0 STEP -1
  189.         IF vstup AND 2 ^ rj THEN DECtoBIN$ = DECtoBIN$ + "1" ELSE DECtoBIN$ = DECtoBIN$ + "0"
  190.     NEXT rj
  191.  

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Mouse pointers
« Reply #1 on: June 09, 2018, 10:48:50 am »
Hi Petr

this is my feedback

very interesting idea... but i got this issue

Hoping that it is useful....
cursor_reader.png
* cursor_reader.png (Filesize: 46.32 KB, Dimensions: 1366x768, Views: 403)
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Mouse pointers
« Reply #2 on: June 09, 2018, 11:51:36 am »
Hi Petr and Tempodibasic,

I had the same report as Tempodibasic so I started tracking down problem.

Things started to work when I removed _HIDE from the SHELL command
Code: QB64: [Select]
  1. SUB MakeCursorsList (Path AS STRING, Mask AS STRING, ToArray() AS STRING)
  2.     '    IF not win THEN PRINT "Error: MakeCursosList SUB is designed for Windows only.": SLEEP 1: END
  3.     Current$ = _CWD$
  4.     'PRINT Path   'OK
  5.     IF _DIREXISTS(Path$) THEN
  6.         'CHDIR Path$   'OK
  7.         PRINT _CWD$
  8.         commandd$ = "DIR " + Mask$ + " /B > CursorsList.txt"
  9.         SHELL commandd$ '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> remove _Hide   aha! now it works
  10.         IF _FILEEXISTS("CursorsList.txt") THEN
  11.             CH = FREEFILE
  12.             OPEN "CursorsList.txt" FOR INPUT AS #CH
  13.             DO WHILE NOT EOF(CH)
  14.                 LINE INPUT #CH, crs$
  15.                 REDIM _PRESERVE ToArray(i) AS STRING
  16.                 ToArray$(i) = LEFT$(crs$, 20)
  17.                 i = i + 1
  18.             LOOP
  19.             CLOSE #CH
  20.         ELSE
  21.             PRINT "Unknown error. File CursorsList.txt not created.": SLEEP 1: END
  22.         END IF
  23.     ELSE
  24.         PRINT "Error (Sub MakeCursorList): Specified path not exists.": SLEEP 1
  25.         EXIT SUB
  26.     END IF
  27.  

probably a coincidence as now it works with _HIDE command, say is that temp file "CursorList.txt" getting KILLED when done with it?
« Last Edit: June 09, 2018, 11:55:58 am by bplus »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Mouse pointers
« Reply #3 on: June 09, 2018, 12:07:51 pm »
Hi Petr! I get error message saying "Unknown error. File CursorsList.txt not created."
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Mouse pointers
« Reply #4 on: June 09, 2018, 12:12:42 pm »
Yeah there still is a problem after file is found, it is empty (being created in same folder as Petr's bas source as Windows wont let you write files in it's folders that I know of...)

So these are screens that follow with an empty cursorlist file and the newimage adjusted to 800x600 so I can access my tool bar. (Man I dislike it immensely when you guys test stuff in full screen!)

PS in test screen there is also giant mouse pointer.

cursor screen 1.PNG
* cursor screen 1.PNG (Filesize: 11.88 KB, Dimensions: 818x288, Views: 351)
Cursor screen 2.PNG
* Cursor screen 2.PNG (Filesize: 25 KB, Dimensions: 1045x680, Views: 452)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Mouse pointers
« Reply #5 on: June 09, 2018, 12:20:12 pm »
Oh dang, it started working because I still had CHDIR commented out, foo!

What if we try and make the cursorlist.txt file in the bas source? That might fix Windows forbidden file making in it's folders.
« Last Edit: June 09, 2018, 12:50:03 pm by bplus »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Mouse pointers
« Reply #6 on: June 09, 2018, 12:23:11 pm »
Oh! It ran successfully with "Run with Administrator". Need not to worry.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Mouse pointers
« Reply #7 on: June 09, 2018, 12:35:26 pm »
Oh that worked! Thanks Ashish, that is handy tip!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Mouse pointers
« Reply #8 on: June 09, 2018, 02:52:15 pm »
Thank you for all your reactions. Good idea, Ashish, I still neglect the possibilities of using hardware images, I will be able to think more about this possibility. I did not think it would be a problem with writing a file in a protected area of windows, I have set my IDE up so that she can do what she wants. But of course, there is no problem and i write this file at source. The only difference is that the file will contain the whole path, not just the .CUR file name. I will issue another source code where this will be fixed (about an hour).

I put it here and went away -  your interest is enjoying me. Stop writing this, i go repair it :-D

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Mouse pointers
« Reply #9 on: June 09, 2018, 03:01:55 pm »
Repaired. Duration cca 1 minute. Small repair in sub MakeCursorList. File contain names, loader (ShowUsableCursors SUB) but use full path returned from ENVIRON$:

Code: QB64: [Select]
  1. 'CUR file reader for read and draw cursor images from /windows/cursors dir. First version.
  2. 'Writed wihtout format knowledge just only on base from https://en.wikipedia.org/wiki/ICO_(file_format)
  3.  
  4.  
  5. 'can you find, how are writed some "unsupported" files?
  6. 'known bug is bad draw Pen big xl.
  7.  
  8. 'writed for fun by Petr
  9.  
  10.  
  11.  
  12. REDIM CursorsList(0) AS STRING
  13. Path$ = ENVIRON$("systemroot") + "\cursors\"
  14. Mask$ = "*.CUR"
  15. MakeCursorsList Path$, Mask$, CursorsList$()
  16.  
  17. Cursor$ = ENVIRON$("systemroot") + "\cursors\aero_arrow.cur"
  18. Img& = LoadCursor&(Cursor$, x, y)
  19.  
  20. PRINT "One cursor is loaded and will be used. This is Cursor loader info screen. Press any key...": SLEEP
  21.  
  22. _DEST my&
  23. CLS , _RGB32(128, 55, 220)
  24. ShowUsableCursors CursorsList$(), my&
  25.  
  26. SCREEN my&
  27.     PCOPY 1, _DISPLAY
  28.     ViewCursor Img&, x, y
  29.     _LIMIT 25
  30.  
  31. SUB ShowUsableCursors (Cursors() AS STRING, ToScreen AS LONG)
  32.     _DEST ToScreen&
  33.     X = 100: y = 100
  34.     FOR L = LBOUND(cursors) TO UBOUND(cursors)
  35.         P$ = ENVIRON$("systemroot") + "\cursors\" + Cursors(L)
  36.         i& = LoadCursor&(P$, a, b)
  37.         _DEST ToScreen&
  38.         IF i& >= 0 THEN GOSUB Unsupported: _CONTINUE
  39.         _PUTIMAGE (X, y), i&, ToScreen&
  40.         _FREEIMAGE i&
  41.         COLOR _RGB32(255, 255, 254), _RGB32(128, 55, 220)
  42.         _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  43.         X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  44.         IF y + 300 > _DESKTOPHEIGHT THEN
  45.             SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  46.             P$ = ""
  47.         END IF
  48.     NEXT L
  49.     _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "New cursor is now used. Press Esc for end.", ToScreen&
  50.     EXIT SUB
  51.  
  52.     Unsupported:
  53.     _PRINTSTRING (X + 20, y + 50), "Not supported", ToScreen&
  54.     _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  55.     X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  56.     IF y + 300 > _DESKTOPHEIGHT THEN
  57.         SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  58.         P$ = ""
  59.     END IF
  60.     RETURN
  61.  
  62. SUB MakeCursorsList (Path AS STRING, Mask AS STRING, ToArray() AS STRING)
  63.     '    IF not win THEN PRINT "Error: MakeCursosList SUB is designed for Windows only.": SLEEP 1: END
  64.     Current$ = _CWD$
  65.     IF _DIREXISTS(Path$) THEN
  66.         'CHDIR Path$
  67.         commandd$ = "DIR " + Path$ + Mask$ + " /B > CursorsList.txt"
  68.         SHELL _HIDE commandd$
  69.         IF _FILEEXISTS("CursorsList.txt") THEN
  70.             CH = FREEFILE
  71.             OPEN "CursorsList.txt" FOR INPUT AS #CH
  72.             DO WHILE NOT EOF(CH)
  73.                 LINE INPUT #CH, crs$
  74.                 REDIM _PRESERVE ToArray(i) AS STRING
  75.  
  76.  
  77.                 ToArray$(i) = LEFT$(crs$, 20)
  78.                 i = i + 1
  79.             LOOP
  80.             CLOSE #CH
  81.         ELSE PRINT "Unknown error. File CursorsList.txt not created.": SLEEP 1: END
  82.         END IF
  83.     ELSE
  84.         PRINT "Error (Sub MakeCursorList): Specified path not exists.": SLEEP 1
  85.         EXIT SUB
  86.     END IF
  87.  
  88. SUB ViewCursor (Cursor AS LONG, ReductionX AS _BYTE, ReductionY AS _BYTE)
  89.     _DEST 0
  90.     _PUTIMAGE (_MOUSEX - ReductionX - 6, _MOUSEY - ReductionY), Cursor&, 0
  91.  
  92. FUNCTION LoadCursor& (Cursor AS STRING, XReturned, YReturned)
  93.     'returns: 1: File not exists, 2: Unsupported format, Value < 0 - valid cursor image
  94.     TYPE CUR
  95.         Reserved AS INTEGER '       2 bytes, always 00
  96.         Image_Type AS INTEGER '     1 = ICO format, 2 = CUR format, others are invalid
  97.         Number_images AS INTEGER '  number images in file
  98.     END TYPE
  99.  
  100.     TYPE Structure
  101.         Image_Width AS _UNSIGNED _BYTE
  102.         Image_Height AS _UNSIGNED _BYTE
  103.         Image_Color_Palette AS _UNSIGNED _BYTE
  104.         Reserved AS _UNSIGNED _BYTE 'always zero
  105.         Horizontal AS INTEGER '      In ICO format: Specifies color planes. Should be 0 or 1.
  106.         '                            In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
  107.         Vertical AS INTEGER '        In ICO format: Specifies bits per pixel.
  108.         '                            In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.
  109.         Size_of_image_data AS LONG
  110.         Offset_from_begin AS LONG
  111.     END TYPE
  112.     SCREEN _NEWIMAGE(800, 600, 32)
  113.     CLS
  114.     ERc = 0
  115.     DIM CUR AS CUR, Structure AS Structure
  116.  
  117.     IF _FILEEXISTS(Cursor$) THEN
  118.         CLOSE #1
  119.         OPEN Cursor$ FOR BINARY AS #1
  120.  
  121.  
  122.         GET #1, , CUR
  123.         PRINT "First 2 bytes (always 0):"; CUR.Reserved
  124.         PRINT "Image type (1 = ICO, 2 = CUR):"; CUR.Image_Type
  125.         PRINT "Number images in file:"; CUR.Number_images
  126.  
  127.         re:
  128.         '   _DEST 0
  129.         PRINT "======================================="; R
  130.         PRINT "Position in file:"; SEEK(1)
  131.         GET #1, , Structure
  132.         PRINT "Image width:"; Structure.Image_Width
  133.         PRINT "Image height:"; Structure.Image_Height
  134.         PRINT "Image color palette: (0 = LONG truecolor, 2 = _UNSIGNED _BYTE?)"; Structure.Image_Color_Palette
  135.         PRINT "Reserved (always zero):"; Structure.Reserved
  136.         PRINT "Number image points from left:"; Structure.Horizontal
  137.         PRINT "Number image points from top: "; Structure.Vertical
  138.         PRINT "Size of image data: "; Structure.Size_of_image_data
  139.         PRINT "Start offset: "; Structure.Offset_from_begin
  140.  
  141.         IF LOF(1) < 10000 AND Structure.Image_Color_Palette = 0 THEN LoadCursor& = 2: EXIT FUNCTION 'some CUR files contains record: Structure.Image_Color_Palette = 0 (LONG) but are saved as CASE 2. If is used CASE 2 program, is then cursor view VERY badly. :-/
  142.  
  143.         XReturned = Structure.Horizontal
  144.         YReturned = Structure.Vertical
  145.  
  146.         A$ = SPACE$(Structure.Size_of_image_data)
  147.         GET #1, , A$
  148.         posice = Structure.Offset_from_begin - 1
  149.  
  150.         IF Structure.Image_Width > 1 AND Structure.Image_Height > 1 THEN
  151.             SELECT CASE Structure.Image_Color_Palette '                                In file is writed 0, but it is 4 byte long depth. Interresting...
  152.                 CASE 0
  153.                     posice = Structure.Offset_from_begin - 1
  154.                     LoadCursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 32)
  155.                     _DEST LoadCursor&
  156.                     FOR DrawY = Structure.Image_Height - 1 TO 0 STEP -1
  157.                         FOR DrawX = 0 TO Structure.Image_Width - 1
  158.                             IF ERc THEN EXIT FOR ' some files contains record as 4 bytes, but are 1 byte! (uses 256 colors, but not truecolor as is recorded in head)
  159.                             Bod& = CVL(MID$(A$, posice, 4))
  160.                             posice = posice + 4
  161.                             PSET (DrawX, DrawY), Bod&
  162.                     NEXT DrawX, DrawY
  163.  
  164.                 CASE 2
  165.                     SEEK #1, posice + 50
  166.                     GET #1, , A$
  167.                     LoadCursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 256) ' 2 bit colored. My lovely. :-D
  168.                     _DEST LoadCursor&
  169.                     _CLEARCOLOR 15, LoadCursor&
  170.                     DrawX = 0: DrawY = 1
  171.                     FOR CursorDraw = 1 TO LEN(A$)
  172.                         Bod = ASC(A$, CursorDraw)
  173.                         Bin$ = DECtoBIN$(Bod)
  174.                         FOR drr = 1 TO LEN(Bin$)
  175.                             comand$ = MID$(Bin$, drr, 1)
  176.                             IF comand$ = "1" THEN clr = 0 ELSE clr = 15
  177.                             PSET (DrawX, Structure.Image_Height - DrawY), clr
  178.                             DrawX = DrawX + 1: IF DrawX > Structure.Image_Width - 1 THEN DrawX = 0: DrawY = DrawY + 1
  179.                         NEXT
  180.                     NEXT
  181.             END SELECT
  182.         END IF
  183.     ELSE LoadCursor& = 1: EXIT FUNCTION 'if file not exists
  184.     END IF
  185.     IF Structure.Image_Color_Palette = 0 THEN _SETALPHA 0, _RGB32(0, 0, 0), Cursor&
  186.     CLOSE #1
  187.     _DEST 0
  188.  
  189. FUNCTION DECtoBIN$ (vstup)
  190.     FOR rj = 7 TO 0 STEP -1
  191.         IF vstup AND 2 ^ rj THEN DECtoBIN$ = DECtoBIN$ + "1" ELSE DECtoBIN$ = DECtoBIN$ + "0"
  192.     NEXT rj
  193.  

preview.jpg
* preview.jpg (Filesize: 66.05 KB, Dimensions: 1680x1050, Views: 375)
« Last Edit: June 09, 2018, 03:05:36 pm by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Mouse pointers
« Reply #10 on: June 09, 2018, 03:27:38 pm »
Here is ancestor CUR viewer. Maybe its easyest. Just rewrite CUR file name on line 25:

Code: QB64: [Select]
  1. 'CUR file reader for read ind draw cursor images from /windows/cursors dir. First version, just for fun.
  2. 'Writed on base https://en.wikipedia.org/wiki/ICO_(file_format)
  3. TYPE CUR
  4.     Reserved AS INTEGER '       2 bytes, always 00
  5.     Image_Type AS INTEGER '     1 = ICO format, 2 = CUR format, others are invalid
  6.     Number_images AS INTEGER '  number images in file
  7.  
  8. TYPE Structure
  9.     Image_Width AS _UNSIGNED _BYTE
  10.     Image_Height AS _UNSIGNED _BYTE
  11.     Image_Color_Palette AS _UNSIGNED _BYTE
  12.     Reserved AS _UNSIGNED _BYTE 'always zero
  13.     Horizontal AS INTEGER '      In ICO format: Specifies color planes. Should be 0 or 1.
  14.     '                            In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
  15.     Vertical AS INTEGER '        In ICO format: Specifies bits per pixel.
  16.     '                            In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.
  17.     Size_of_image_data AS LONG
  18.     Offset_from_begin AS LONG
  19. SCREEN _NEWIMAGE(800, 600, 32)
  20. CLS , _RGB32(128, 100, 250)
  21. ERc = 0
  22. DIM CUR AS CUR, Structure AS Structure
  23. Cursor$ = ENVIRON$("systemroot") + "\cursors\up_i.cur"
  24. OPEN Cursor$ FOR BINARY AS #1
  25.  
  26.  
  27. GET #1, , CUR
  28. PRINT "First 2 bytes (always 0):"; CUR.Reserved
  29. PRINT "Image type (1 = ICO, 2 = CUR):"; CUR.Image_Type
  30. PRINT "Number images in file:"; CUR.Number_images
  31.  
  32. re:
  33. PRINT "======================================="; R
  34. GET #1, , Structure
  35. PRINT "Image width:"; Structure.Image_Width
  36. PRINT "Image height:"; Structure.Image_Height
  37. PRINT "Image color palette: (0 = LONG truecolor, 2 = _UNSIGNED _BYTE?)"; Structure.Image_Color_Palette
  38. PRINT "Reserved (always zero):"; Structure.Reserved
  39. PRINT "Number image points from left:"; Structure.Horizontal
  40. PRINT "Number image points from top: "; Structure.Vertical
  41. PRINT "Size of image data: "; Structure.Size_of_image_data
  42. PRINT "Start offset: "; Structure.Offset_from_begin
  43.  
  44. IF LOF(1) < 10000 AND Structure.Image_Color_Palette = 0 THEN PRINT "Unsupported file format": END
  45.  
  46. A$ = SPACE$(Structure.Size_of_image_data)
  47. GET #1, , A$
  48. posice = Structure.Offset_from_begin - 1
  49.  
  50. IF Structure.Image_Width > 1 AND Structure.Image_Height > 1 THEN
  51.     SELECT CASE Structure.Image_Color_Palette '                                  File write 0, but it is 4 byte long depth. Interresting...
  52.         CASE 0
  53.             posice = Structure.Offset_from_begin - 1
  54.             cursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 32)
  55.             _DEST cursor&
  56.             FOR DrawY = Structure.Image_Height - 1 TO 0 STEP -1
  57.                 FOR DrawX = 0 TO Structure.Image_Width - 1
  58.                     IF ERc THEN EXIT FOR ' some files contains record as 4 bytes, but are 1 byte! (uses 256 colors, but not truecolor as is recorded in head)
  59.                     Bod& = CVL(MID$(A$, posice, 4))
  60.                     posice = posice + 4
  61.                     PSET (DrawX, DrawY), Bod&
  62.             NEXT DrawX, DrawY
  63.  
  64.  
  65.         CASE 2
  66.             SEEK #1, posice + 50
  67.             GET #1, , A$
  68.             cursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 256) ' 2 bit colored. My lovely. :-D
  69.             _DEST cursor&
  70.             _CLEARCOLOR 15, cursor&
  71.             DrawX = 0: DrawY = 1
  72.             FOR CursorDraw = 1 TO LEN(A$)
  73.                 Bod = ASC(A$, CursorDraw)
  74.                 Bin$ = DECtoBIN$(Bod)
  75.                 FOR drr = 1 TO LEN(Bin$)
  76.                     comand$ = MID$(Bin$, drr, 1)
  77.                     IF comand$ = "1" THEN clr = 0 ELSE clr = 15
  78.                     PSET (DrawX, Structure.Image_Height - DrawY), clr
  79.                     DrawX = DrawX + 1: IF DrawX > Structure.Image_Width - 1 THEN DrawX = 0: DrawY = DrawY + 1
  80.                 NEXT
  81.             NEXT
  82.     END SELECT
  83.  
  84. IF Structure.Image_Color_Palette = 0 THEN _SETALPHA 0, _RGB32(0, 0, 0), cursor&
  85. 'SCREEN cursor&: SLEEP
  86.  
  87.     PCOPY 1, _DISPLAY
  88.     Cx = Structure.Image_Width / 2: Cy = Structure.Image_Height / 2
  89.     _PUTIMAGE (_MOUSEX - Cx, _MOUSEY - Cy), cursor&, 0
  90.     _DISPLAY
  91.     _LIMIT 25
  92.  
  93. FUNCTION DECtoBIN$ (vstup) 'DEC to BIN ok vystup je string, vstup je integer          decimal to binary number convertor   -   FROM QB64WIKI
  94.     FOR rj = 7 TO 0 STEP -1
  95.         IF vstup AND 2 ^ rj THEN DECtoBIN$ = DECtoBIN$ + "1" ELSE DECtoBIN$ = DECtoBIN$ + "0"
  96.     NEXT rj
  97.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Mouse pointers
« Reply #11 on: June 09, 2018, 04:05:18 pm »
Yep, works fine now for my system.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Mouse pointers
« Reply #12 on: June 11, 2018, 10:08:20 am »
So I can confirm that now it works fine...
Thank's
Programming isn't difficult, only it's  consuming time and coffee

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Mouse pointers
« Reply #13 on: August 20, 2018, 03:39:28 pm »
Here's another version. Tested under Windows and under Linux MINT. Unfortunately, in Linux, an unknown thing causes the program not hide the mouse pointer and not show a new pointer, but it gets stuck. That's why I've enabled the setting of the pointer under Windows only. I'm a newbie under Linux and I just know not why in Linux it works not. The error is in something in the SUB VIEWCURSOR, if someone wanted to advise me. The attachment contains CUR files for Linux users. Windows users do not need this attachment, in Windows it is read from the Windows \ Cursors folder.

This version supports more CUR file types.

Code: QB64: [Select]
  1. 'CUR file reader for read and draw cursor images from /windows/cursors dir. First version.
  2. 'Writed wihtout format knowledge just only on base from https://en.wikipedia.org/wiki/ICO_(file_format)
  3.  
  4.  
  5. 'can you find, how are writed some "unsupported" files?      Upgraded (type 16 supported uncorrectly), type 0, 2 already supported
  6. 'known bug is bad draw Pen big xl.                           Repaired
  7. 'is added LINUX SUPPORT.   (tested in Linux MINT)...
  8. 'known bug: Can not correctly draw structure color palette type 16. Its set to optimal output, but picture, as is set in file is then returned in different width and height image. (help_il.cur, help_im.cur)
  9.  
  10.  
  11.  
  12. 'writed for fun by Petr
  13.  
  14.  
  15.  
  16. DIM SHARED ACTIVE ' variable, which memorize new mouse cursor usage. Used in ViewCursor SUB
  17.  
  18. REDIM CursorsList(0) AS STRING
  19. IF WIN THEN Path$ = ENVIRON$("systemroot") + "\cursors\" ELSE Path$ = _CWD$
  20. Mask$ = "*.cur"
  21.  
  22.  
  23.  
  24.  
  25. MakeCursorsList Path$, Mask$, CursorsList$() '                  show all cursors on screen
  26. IF WIN THEN
  27.     Cursor$ = ENVIRON$("systemroot") + "\cursors\wait_m.cur" '  Windows - read cursors from Your Windows path\Cursors\
  28.     Img& = LoadCursor&(Cursor$, x, y)
  29.     Img& = LoadCursor&(_CWD$ + "/wait_m.cur", x, y) '           Linux - read cursors from program directory
  30.  
  31.  
  32. _DEST my&
  33. CLS , _RGB32(128, 55, 220)
  34. ShowUsableCursors CursorsList$(), my&
  35.  
  36. SCREEN my&
  37.  
  38.     K& = _KEYDOWN(27)
  39.     PCOPY 1, _DISPLAY
  40.     IF WIN THEN ViewCursor Img&, x, y 'in LINUX is here something wrong. Program then show not new mouse cursor and gets stuck. WHY?
  41.     _LIMIT 25
  42.  
  43. SUB ShowUsableCursors (Cursors() AS STRING, ToScreen AS LONG)
  44.     _DEST ToScreen&
  45.     X = 100: y = 100
  46.     FOR L = LBOUND(cursors) TO UBOUND(cursors)
  47.  
  48.         i& = LoadCursor&(Cursors(L), A, b)
  49.         _DEST ToScreen&
  50.         IF i& >= 0 THEN GOSUB Unsupported: _CONTINUE
  51.         _PUTIMAGE (X, y), i&, ToScreen&
  52.         _FREEIMAGE i&
  53.         COLOR _RGB32(255, 255, 254), _RGB32(128, 55, 220)
  54.         _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  55.         X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  56.         IF y + 300 > _DESKTOPHEIGHT THEN
  57.             SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  58.             P$ = ""
  59.         END IF
  60.     NEXT L
  61.     _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "New cursor is now used. Press Esc for end.", ToScreen&
  62.     EXIT SUB
  63.  
  64.     Unsupported:
  65.     _PRINTSTRING (X + 20, y + 50), "Not supported", ToScreen&
  66.     _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  67.     X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  68.     IF y + 300 > _DESKTOPHEIGHT THEN
  69.         SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  70.         P$ = ""
  71.     END IF
  72.     RETURN
  73.  
  74. SUB MakeCursorsList (Path AS STRING, Mask AS STRING, ToArray() AS STRING)
  75.     '    IF not win THEN PRINT "Error: MakeCursosList SUB is designed for Windows only.": SLEEP 1: END     'now supported.
  76.     Current$ = _CWD$
  77.     IF _DIREXISTS(Path$) THEN
  78.         CHDIR Path$
  79.         IF WIN THEN commandd$ = "DIR " + Mask$ + " /B > CursorsList.txt" ELSE commandd$ = "ls " + Mask$ + "> CursorsList.txt"
  80.         '        PRINT commandd$
  81.         '       SLEEP
  82.         SHELL commandd$
  83.  
  84.         ' SLEEP
  85.         IF _FILEEXISTS("CursorsList.txt") THEN
  86.             CH = FREEFILE
  87.             OPEN "CursorsList.txt" FOR INPUT AS #CH
  88.             DO WHILE NOT EOF(CH)
  89.                 LINE INPUT #CH, crs$
  90.                 REDIM _PRESERVE ToArray(i) AS STRING
  91.  
  92.  
  93.                 ToArray$(i) = LEFT$(crs$, 20)
  94.                 i = i + 1
  95.             LOOP
  96.             CLOSE #CH
  97.         ELSE PRINT "Unknown error. File CursorsList.txt not created.": SLEEP 1: END
  98.         END IF
  99.     ELSE
  100.         PRINT "Error (Sub MakeCursorList): Specified path not exists.": SLEEP 1
  101.         EXIT SUB
  102.     END IF
  103.  
  104. SUB ViewCursor (Cursor AS LONG, ReductionX AS _BYTE, ReductionY AS _BYTE)
  105.  
  106.     _DEST 0
  107.     IF ACTIVE = 0 THEN ACTIVE = 1: _MOUSEMOVE _MOUSEX, _MOUSEY ' because without mouse moving is not _MOUSEHIDE accepted after call _MOUSEHIDE
  108.     _PUTIMAGE (_MOUSEX - ReductionX - 6, _MOUSEY - ReductionY), Cursor&, 0
  109.  
  110. FUNCTION LoadCursor& (Cursor AS STRING, XReturned, YReturned)
  111.     IF LoadCursor& THEN _FREEIMAGE LoadCursor&
  112.     'returns: 1: File not exists, 2: Unsupported format, Value < 0 - valid cursor image
  113.     TYPE CUR
  114.         Reserved AS INTEGER '       2 bytes, always 00
  115.         Image_Type AS INTEGER '     1 = ICO format, 2 = CUR format, others are invalid
  116.         Number_images AS INTEGER '  number images in file
  117.     END TYPE
  118.  
  119.     TYPE Structure
  120.         Image_Width AS _UNSIGNED _BYTE
  121.         Image_Height AS _UNSIGNED _BYTE
  122.         Image_Color_Palette AS _BYTE '_UNSIGNED _BYTE
  123.         Reserved AS _UNSIGNED _BYTE 'always zero
  124.         Horizontal AS INTEGER '      In ICO format: Specifies color planes. Should be 0 or 1.
  125.         '                            In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
  126.         Vertical AS INTEGER '        In ICO format: Specifies bits per pixel.
  127.         '                            In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.
  128.         Size_of_image_data AS LONG
  129.         Offset_from_begin AS LONG
  130.     END TYPE
  131.  
  132.     TYPE ClrMask ' Thanks to LINUX i see difference. THIS area is not mentoied in my source materials...
  133.         Bb AS _UNSIGNED _BYTE
  134.         Gb AS _UNSIGNED _BYTE
  135.         Rb AS _UNSIGNED _BYTE 'colors use 3 colors, not alpha. Background color.
  136.         Bf AS _UNSIGNED _BYTE
  137.         Gf AS _UNSIGNED _BYTE
  138.         Rf AS _UNSIGNED _BYTE '                                Foreground color.
  139.     END TYPE
  140.     DIM Mask AS ClrMask
  141.  
  142.     SCREEN _NEWIMAGE(800, 600, 32)
  143.     CLS
  144.     ERc = 0
  145.     DIM CUR AS CUR, Structure AS Structure
  146.  
  147.     IF _FILEEXISTS(Cursor$) THEN
  148.         CLOSE #1
  149.  
  150.         SHARED po: po = po + 1
  151.         OPEN Cursor$ FOR BINARY AS #1
  152.  
  153.         GET #1, , CUR
  154.         PRINT "First 2 bytes (always 0):"; CUR.Reserved
  155.         PRINT "Image type (1 = ICO, 2 = CUR):"; CUR.Image_Type
  156.         PRINT "Number images in file:"; CUR.Number_images
  157.  
  158.         re:
  159.  
  160.         PRINT "======================================="; R
  161.         PRINT "File: "; Cursor$; po - 2
  162.         PRINT "Position in file:"; SEEK(1)
  163.         GET #1, , Structure
  164.         PRINT "Image width:"; Structure.Image_Width
  165.         PRINT "Image height:"; Structure.Image_Height
  166.         PRINT "Image color palette: (0 = LONG truecolor, 2 = _UNSIGNED _BYTE?)"; Structure.Image_Color_Palette
  167.         PRINT "Reserved (always zero):"; Structure.Reserved
  168.         PRINT "Number image points from left:"; Structure.Horizontal
  169.         PRINT "Number image points from top: "; Structure.Vertical
  170.         PRINT "Size of image data: "; Structure.Size_of_image_data
  171.         PRINT "Start offset: "; Structure.Offset_from_begin
  172.         PRINT " Palette:"; Structure.Image_Color_Palette
  173.         PRINT "File size: "; LOF(1)
  174.  
  175.  
  176.  
  177.         FOR all_images = 1 TO CUR.Number_images
  178.             GET #1, , Mask
  179.             PRINT "Image: "; all_images
  180.             PRINT "Color mask - foreground: "; Mask.Rf; Mask.Gf; Mask.Bf
  181.             PRINT "Color mask - background: "; Mask.Rb; Mask.Gb; Mask.Bb
  182.             _DELAY .1
  183.  
  184.  
  185.             XReturned = Structure.Horizontal
  186.             YReturned = Structure.Vertical
  187.  
  188.             A$ = SPACE$(Structure.Size_of_image_data)
  189.             posice = Structure.Offset_from_begin + 1
  190.  
  191.             IF Structure.Image_Width > 1 AND Structure.Image_Height > 1 THEN
  192.                 SELECT CASE Structure.Image_Color_Palette '                                In file is writed 0, but it is 4 byte long depth. Interresting...
  193.                     CASE 0
  194.                         SEEK #1, Structure.Offset_from_begin + 1
  195.                         GET #1, , A$
  196.                         posice = Structure.Offset_from_begin - 1
  197.                         IF Structure.Size_of_image_data < (Structure.Image_Width * Structure.Image_Height) THEN ClrDepth = 256 ELSE ClrDepth = 32
  198.                         LoadCursor& = _NEWIMAGE(Structure.Image_Width + 1, Structure.Image_Height + 1, ClrDepth)
  199.  
  200.  
  201.                         _DEST LoadCursor&
  202.                         IF drawy = 0 THEN drawy = Structure.Image_Height
  203.                         IF ClrDepth = 32 THEN
  204.                             DO WHILE drawy <> 0 AND drawx <> Structure.Image_Width
  205.                                 posice = posice + 4
  206.                                 Bod& = CVL(MID$(A$, posice, 4))
  207.                                 PSET (drawx, drawy), Bod&
  208.                                 drawx = drawx + 1
  209.                                 IF drawx = Structure.Image_Width AND drawx MOD 4 = 0 THEN drawx = 0: drawy = drawy - 1
  210.                             LOOP
  211.                         ELSE
  212.                             'upgrade
  213.                             SEEK #1, Structure.Offset_from_begin
  214.                             GET #1, , A$
  215.                             drawy = -2
  216.                             LoadCursor& = _NEWIMAGE(Structure.Image_Width + 1, Structure.Image_Height + 1, 256) ' 2 bit color
  217.                             _DEST LoadCursor&
  218.                             _PALETTECOLOR 1, _RGB32(Mask.Rf, Mask.Gf, Mask.Bf)
  219.                             _PALETTECOLOR 15, _RGB32(Mask.Rb, Mask.Gb, Mask.Bb)
  220.                             _CLEARCOLOR 1, LoadCursor&
  221.                             drawx = -8: drawy = -6
  222.                             FOR CursorDraw = 1 TO LEN(A$)
  223.                                 bod = ASC(A$, CursorDraw)
  224.                                 Bin$ = DECtoBIN$(bod)
  225.                                 FOR drr = 1 TO LEN(Bin$)
  226.                                     comand$ = MID$(Bin$, drr, 1)
  227.                                     IF comand$ = "1" THEN clr = 15 ELSE clr = 1
  228.  
  229.                                     IF drawy < 0 THEN clr = 1
  230.                                     IF drawy > -2 THEN PSET (drawx, (Structure.Image_Height - 1) - drawy), clr
  231.                                     drawx = drawx + 1: IF drawx >= Structure.Image_Width AND drawx MOD 32 = 0 THEN drawx = 0: drawy = drawy + 1
  232.                                 NEXT
  233.                             NEXT
  234.                         END IF
  235.  
  236.                     CASE 2
  237.                         SEEK #1, Structure.Offset_from_begin + 45
  238.                         GET #1, , A$
  239.                         LoadCursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 256) ' 2 bit colored. My lovely. :-D
  240.                         _DEST LoadCursor&
  241.  
  242.                         _PALETTECOLOR 1, _RGB32(Mask.Rf, Mask.Gf, Mask.Bf)
  243.                         _PALETTECOLOR 15, _RGB32(Mask.Rb, Mask.Gb, Mask.Bb)
  244.  
  245.  
  246.                         _CLEARCOLOR 1, LoadCursor&
  247.                         drawx = 0: drawy = 0
  248.                         FOR CursorDraw = 1 TO LEN(A$)
  249.                             bod = ASC(A$, CursorDraw)
  250.                             Bin$ = DECtoBIN$(bod)
  251.                             FOR drr = 1 TO LEN(Bin$)
  252.                                 comand$ = MID$(Bin$, drr, 1)
  253.                                 IF comand$ = "1" THEN clr = 15 ELSE clr = 1
  254.                                 PSET (drawx, Structure.Image_Height - drawy), clr
  255.                                 drawx = drawx + 1: IF drawx > Structure.Image_Width - 1 AND drawx MOD 32 = 0 THEN drawx = 0: drawy = drawy + 1
  256.                             NEXT
  257.                         NEXT
  258.  
  259.                     CASE 16
  260.                         SEEK #1, Structure.Offset_from_begin + 817 'i have none informations about file area between color palette record and image data record...
  261.  
  262.                         GET #1, , A$
  263.                         A$ = LEFT$(A$, Structure.Image_Width * Structure.Image_Height)
  264.                         LoadCursor& = _NEWIMAGE(Structure.Image_Width + 12, Structure.Image_Height + 5, 256) '
  265.                         _DEST LoadCursor&
  266.                         _PALETTECOLOR 15, _RGB32(Mask.Rf, Mask.Gf, Mask.Bf)
  267.                         _PALETTECOLOR 1, _RGB32(Mask.Rb, Mask.Gb, Mask.Bb)
  268.                         _CLEARCOLOR 1, LoadCursor&
  269.  
  270.                         drawx = -3: drawy = -4 'Structure.Vertical
  271.                         FOR CursorDraw = 1 TO LEN(A$)
  272.                             bod = ASC(A$, CursorDraw)
  273.                             Bin$ = DECtoBIN$(bod)
  274.                             FOR drr = 1 TO LEN(Bin$)
  275.                                 comand$ = MID$(Bin$, drr, 1)
  276.                                 IF comand$ = "1" THEN clr = 15 ELSE clr = 1
  277.                                 PSET (drawx, Structure.Image_Height - drawy), clr
  278.                                 drawx = drawx + 1: IF drawx > Structure.Image_Width AND drawx MOD 32 = 0 THEN drawx = 0: drawy = drawy + 1
  279.                             NEXT
  280.                         NEXT
  281.                 END SELECT
  282.             END IF
  283.         NEXT ' color palette settings
  284.  
  285.     ELSE LoadCursor& = 1: EXIT FUNCTION 'if file not exists
  286.     END IF
  287.     IF Structure.Image_Color_Palette = 0 THEN _SETALPHA 0, _RGB32(0, 0, 0), cursor&
  288.     CLOSE #1
  289.     _DEST 0
  290.  
  291. FUNCTION DECtoBIN$ (vstup)
  292.     FOR rj = 7 TO 0 STEP -1
  293.         IF vstup AND 2 ^ rj THEN DECtoBIN$ = DECtoBIN$ + "1" ELSE DECtoBIN$ = DECtoBIN$ + "0"
  294.     NEXT rj
  295.  
  296. FUNCTION BINtoDEC (b AS STRING)
  297.     FOR Si = 1 TO LEN(b)
  298.         e$ = MID$(b$, Si, 1)
  299.         c = VAL(e$) '
  300.         Sj = LEN(b) - Si
  301.         BINtoDEC = BINtoDEC + (c * 2 ^ Sj)
  302.     NEXT Si
  303.  
  304.     IF INSTR(_OS$, "WINDOWS") THEN WIN = 1 ELSE WIN = 0
  305.  
* Cursors.zip (Filesize: 85.39 KB, Downloads: 167)

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Mouse pointers
« Reply #14 on: August 21, 2018, 12:24:20 pm »
I am sorry, but i found bug.... after test program in windows and linux (and some repairs in linux) i test it not again in windows.... here is repaired version

Code: QB64: [Select]
  1. 'CUR file reader for read and draw cursor images from /windows/cursors dir. First version.
  2. 'Writed wihtout format knowledge just only on base from https://en.wikipedia.org/wiki/ICO_(file_format)
  3.  
  4.  
  5. 'can you find, how are writed some "unsupported" files?      Upgraded (type 16 supported uncorrectly), type 0, 2 already supported
  6. 'known bug is bad draw Pen big xl.                           Repaired
  7. 'is added LINUX SUPPORT.   (tested in Linux MINT)...
  8. 'known bug: Can not correctly draw structure color palette type 16. Its set to optimal output, but picture, as is set in file is then returned in different width and height image. (help_il.cur, help_im.cur)
  9.  
  10. 'Retested in Windows, repaired under Linux.
  11.  
  12. 'writed for fun by Petr
  13.  
  14.  
  15.  
  16. DIM SHARED ACTIVE ' variable, which memorize new mouse cursor usage. Used in ViewCursor SUB
  17.  
  18. REDIM CursorsList(0) AS STRING
  19. IF WIN THEN Path$ = ENVIRON$("systemroot") + "\cursors\" ELSE Path$ = _CWD$
  20. Mask$ = "*.cur"
  21.  
  22.  
  23.  
  24.  
  25. MakeCursorsList Path$, Mask$, CursorsList$() '                  show all cursors on screen
  26. IF WIN THEN
  27.     Cursor$ = ENVIRON$("systemroot") + "\cursors\wait_m.cur" '  Windows - read cursors from Your Windows path\Cursors\
  28.     Img& = LoadCursor&(Cursor$, x, y)
  29.     Img& = LoadCursor&("wait_m.cur", x, y) '           Linux - read cursors from program directory
  30.     '  PRINT Img&: SLEEP
  31.  
  32.  
  33. _DEST my&
  34. CLS , _RGB32(128, 55, 220)
  35. ShowUsableCursors CursorsList$(), my&
  36.  
  37. SCREEN my&
  38.     K& = _KEYDOWN(27)
  39.     PCOPY 1, _DISPLAY
  40.     ViewCursor Img&, x, y 'in LINUX is here something wrong. Program then show not new mouse cursor and gets stuck. WHY?
  41.     _LIMIT 25
  42.  
  43. SUB ShowUsableCursors (Cursors() AS STRING, ToScreen AS LONG)
  44.     _DEST ToScreen&
  45.     X = 100: y = 100
  46.     FOR L = LBOUND(cursors) TO UBOUND(cursors)
  47.  
  48.         i& = LoadCursor&(Cursors(L), A, b)
  49.         _DEST ToScreen&
  50.         IF i& >= 0 THEN GOSUB Unsupported: _CONTINUE
  51.         _PUTIMAGE (X, y), i&, ToScreen&
  52.         _FREEIMAGE i&
  53.         COLOR _RGB32(255, 255, 254), _RGB32(128, 55, 220)
  54.  
  55.         Lp = LastPos(Cursors(L), CHR$(92))
  56.  
  57.         fname$ = MID$(Cursors(L), Lp)
  58.         _PRINTSTRING (X, y + 80), STR$(L) + ": " + fname$, ToScreen&
  59.         X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  60.         IF y + 300 > _DESKTOPHEIGHT THEN
  61.             SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  62.             P$ = ""
  63.         END IF
  64.     NEXT L
  65.     _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "New cursor is now used. Press Esc for end.", ToScreen&
  66.     EXIT SUB
  67.  
  68.     Unsupported:
  69.     _PRINTSTRING (X + 20, y + 50), "Not supported", ToScreen&
  70.     _PRINTSTRING (X, y + 80), STR$(L) + ": " + Cursors(L), ToScreen&
  71.     X = X + 300: IF X > _DESKTOPWIDTH - 300 THEN X = 100: y = y + 300
  72.     IF y + 300 > _DESKTOPHEIGHT THEN
  73.         SCREEN ToScreen&: _PRINTSTRING (20, _DESKTOPHEIGHT - 20), "Press any key for view next...", ToScreen&: SLEEP: CLS , _RGB32(128, 55, 220): X = 100: y = 100
  74.         P$ = ""
  75.     END IF
  76.     RETURN
  77.  
  78. SUB MakeCursorsList (Path AS STRING, Mask AS STRING, ToArray() AS STRING)
  79.     '    IF not win THEN PRINT "Error: MakeCursosList SUB is designed for Windows only.": SLEEP 1: END     'now supported.
  80.     Current$ = _CWD$
  81.     IF _DIREXISTS(Path$) THEN
  82.         '        CHDIR Path$
  83.         IF WIN THEN commandd$ = "DIR " + Path$ + Mask$ + " /B >CursorsList.txt" ELSE commandd$ = "ls " + Mask$ + "> CursorsList.txt"
  84.         SHELL commandd$
  85.  
  86.  
  87.         IF _FILEEXISTS("CursorsList.txt") THEN
  88.             CH = FREEFILE
  89.             OPEN "CursorsList.txt" FOR INPUT AS #CH
  90.             DO WHILE NOT EOF(CH)
  91.                 LINE INPUT #CH, crs$
  92.                 REDIM _PRESERVE ToArray(i) AS STRING
  93.  
  94.  
  95.                 IF WIN THEN
  96.                     ToArray$(i) = Path$ + LEFT$(crs$, 20)
  97.                 ELSE ToArray$(i) = LEFT$(crs$, 20)
  98.                 END IF
  99.  
  100.  
  101.  
  102.                 i = i + 1
  103.             LOOP
  104.             CLOSE #CH
  105.         ELSE PRINT "Unknown error. File CursorsList.txt not created.": SLEEP 1: END
  106.         END IF
  107.     ELSE
  108.         PRINT "Error (Sub MakeCursorList): Specified path not exists.": SLEEP 1
  109.         EXIT SUB
  110.     END IF
  111.  
  112. SUB ViewCursor (Cursor AS LONG, ReductionX AS _BYTE, ReductionY AS _BYTE)
  113.  
  114.     _DEST 0
  115.     IF WIN THEN _MOUSEHIDE ' this create program working fail. Program not respond and can not be killed in LINUX   - but is called in my loop and there works under Linux... ????
  116.     IF ACTIVE = 0 AND WIN THEN ACTIVE = 1: _MOUSEMOVE _MOUSEX, _MOUSEY ' because without mouse moving is not _MOUSEHIDE accepted after call _MOUSEHIDE. If is call in Linux, nothing is viewed, but program can be killed.
  117.     _PUTIMAGE (_MOUSEX - ReductionX - 6, _MOUSEY - ReductionY), Cursor&, 0
  118.  
  119. FUNCTION LoadCursor& (Cursor AS STRING, XReturned, YReturned)
  120.     '    IF LoadCursor& THEN _FREEIMAGE LoadCursor&      'This.... in linux it kill cursor image. In windows it KILL NOT cursor image (image in end)
  121.     'returns: 1: File not exists, 2: Unsupported format, Value < 0 - valid cursor image
  122.     TYPE CUR
  123.         Reserved AS INTEGER '       2 bytes, always 00
  124.         Image_Type AS INTEGER '     1 = ICO format, 2 = CUR format, others are invalid
  125.         Number_images AS INTEGER '  number images in file
  126.     END TYPE
  127.  
  128.     TYPE Structure
  129.         Image_Width AS _UNSIGNED _BYTE
  130.         Image_Height AS _UNSIGNED _BYTE
  131.         Image_Color_Palette AS _BYTE '_UNSIGNED _BYTE
  132.         Reserved AS _UNSIGNED _BYTE 'always zero
  133.         Horizontal AS INTEGER '      In ICO format: Specifies color planes. Should be 0 or 1.
  134.         '                            In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
  135.         Vertical AS INTEGER '        In ICO format: Specifies bits per pixel.
  136.         '                            In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.
  137.         Size_of_image_data AS LONG
  138.         Offset_from_begin AS LONG
  139.     END TYPE
  140.  
  141.     TYPE ClrMask ' Thanks to LINUX i see difference. THIS area is not mentoied in my source materials...
  142.         Bb AS _UNSIGNED _BYTE
  143.         Gb AS _UNSIGNED _BYTE
  144.         Rb AS _UNSIGNED _BYTE 'colors use 3 colors, not alpha. Background color.
  145.         Bf AS _UNSIGNED _BYTE
  146.         Gf AS _UNSIGNED _BYTE
  147.         Rf AS _UNSIGNED _BYTE '                                Foreground color.
  148.     END TYPE
  149.     DIM Mask AS ClrMask
  150.  
  151.     SCREEN _NEWIMAGE(800, 600, 32)
  152.     CLS
  153.     ERc = 0
  154.     DIM CUR AS CUR, Structure AS Structure
  155.  
  156.     IF _FILEEXISTS(Cursor$) THEN
  157.         CLOSE #1
  158.  
  159.         SHARED po: po = po + 1
  160.         OPEN Cursor$ FOR BINARY AS #1
  161.  
  162.         GET #1, , CUR
  163.         PRINT "First 2 bytes (always 0):"; CUR.Reserved
  164.         PRINT "Image type (1 = ICO, 2 = CUR):"; CUR.Image_Type
  165.         PRINT "Number images in file:"; CUR.Number_images
  166.  
  167.         re:
  168.  
  169.         PRINT "======================================="; R
  170.         PRINT "File: "; Cursor$; po - 2
  171.         PRINT "Position in file:"; SEEK(1)
  172.         GET #1, , Structure
  173.         PRINT "Image width:"; Structure.Image_Width
  174.         PRINT "Image height:"; Structure.Image_Height
  175.         PRINT "Image color palette: (0 = LONG truecolor, 2 = _UNSIGNED _BYTE?)"; Structure.Image_Color_Palette
  176.         PRINT "Reserved (always zero):"; Structure.Reserved
  177.         PRINT "Number image points from left:"; Structure.Horizontal
  178.         PRINT "Number image points from top: "; Structure.Vertical
  179.         PRINT "Size of image data: "; Structure.Size_of_image_data
  180.         PRINT "Start offset: "; Structure.Offset_from_begin
  181.         PRINT " Palette:"; Structure.Image_Color_Palette
  182.         PRINT "File size: "; LOF(1)
  183.  
  184.  
  185.  
  186.         FOR all_images = 1 TO CUR.Number_images
  187.             GET #1, , Mask
  188.             PRINT "Image: "; all_images
  189.             PRINT "Color mask - foreground: "; Mask.Rf; Mask.Gf; Mask.Bf
  190.             PRINT "Color mask - background: "; Mask.Rb; Mask.Gb; Mask.Bb
  191.             _DELAY .1
  192.  
  193.  
  194.             XReturned = Structure.Horizontal
  195.             YReturned = Structure.Vertical
  196.  
  197.             A$ = SPACE$(Structure.Size_of_image_data)
  198.             posice = Structure.Offset_from_begin + 1
  199.  
  200.             IF Structure.Image_Width > 1 AND Structure.Image_Height > 1 THEN
  201.                 SELECT CASE Structure.Image_Color_Palette '                                In file is writed 0, but it is 4 byte long depth. Interresting...
  202.                     CASE 0
  203.                         SEEK #1, Structure.Offset_from_begin + 1
  204.                         GET #1, , A$
  205.                         posice = Structure.Offset_from_begin - 1
  206.                         IF Structure.Size_of_image_data < (Structure.Image_Width * Structure.Image_Height) THEN ClrDepth = 256 ELSE ClrDepth = 32
  207.                         LoadCursor& = _NEWIMAGE(Structure.Image_Width + 1, Structure.Image_Height + 1, ClrDepth)
  208.  
  209.  
  210.                         _DEST LoadCursor&
  211.                         IF drawy = 0 THEN drawy = Structure.Image_Height
  212.                         IF ClrDepth = 32 THEN
  213.                             DO WHILE drawy <> 0 AND drawx <> Structure.Image_Width
  214.                                 posice = posice + 4
  215.                                 Bod& = CVL(MID$(A$, posice, 4))
  216.                                 PSET (drawx, drawy), Bod&
  217.                                 drawx = drawx + 1
  218.                                 IF drawx = Structure.Image_Width AND drawx MOD 4 = 0 THEN drawx = 0: drawy = drawy - 1
  219.                             LOOP
  220.                         ELSE
  221.                             'upgrade
  222.                             SEEK #1, Structure.Offset_from_begin
  223.                             GET #1, , A$
  224.                             drawy = -2
  225.                             LoadCursor& = _NEWIMAGE(Structure.Image_Width + 1, Structure.Image_Height + 1, 256) ' 2 bit color
  226.                             _DEST LoadCursor&
  227.                             _PALETTECOLOR 1, _RGB32(Mask.Rf, Mask.Gf, Mask.Bf)
  228.                             _PALETTECOLOR 15, _RGB32(Mask.Rb, Mask.Gb, Mask.Bb)
  229.                             _CLEARCOLOR 1, LoadCursor&
  230.                             drawx = -8: drawy = -6
  231.                             FOR CursorDraw = 1 TO LEN(A$)
  232.                                 bod = ASC(A$, CursorDraw)
  233.                                 Bin$ = DECtoBIN$(bod)
  234.                                 FOR drr = 1 TO LEN(Bin$)
  235.                                     comand$ = MID$(Bin$, drr, 1)
  236.                                     IF comand$ = "1" THEN clr = 15 ELSE clr = 1
  237.  
  238.                                     IF drawy < 0 THEN clr = 1
  239.                                     IF drawy > -2 THEN PSET (drawx, (Structure.Image_Height - 1) - drawy), clr
  240.                                     drawx = drawx + 1: IF drawx >= Structure.Image_Width AND drawx MOD 32 = 0 THEN drawx = 0: drawy = drawy + 1
  241.                                 NEXT
  242.                             NEXT
  243.                         END IF
  244.  
  245.                     CASE 2
  246.                         SEEK #1, Structure.Offset_from_begin + 45
  247.                         GET #1, , A$
  248.                         LoadCursor& = _NEWIMAGE(Structure.Image_Width, Structure.Image_Height, 256) ' 2 bit colored. My lovely. :-D
  249.                         _DEST LoadCursor&
  250.  
  251.                         _PALETTECOLOR 1, _RGB32(Mask.Rf, Mask.Gf, Mask.Bf)
  252.                         _PALETTECOLOR 15, _RGB32(Mask.Rb, Mask.Gb, Mask.Bb)
  253.  
  254.  
  255.                         _CLEARCOLOR 1, LoadCursor&
  256.                         drawx = 0: drawy = 0
  257.                         FOR CursorDraw = 1 TO LEN(A$)
  258.                             bod = ASC(A$, CursorDraw)
  259.                             Bin$ = DECtoBIN$(bod)
  260.                             FOR drr = 1 TO LEN(Bin$)
  261.                                 comand$ = MID$(Bin$, drr, 1)
  262.                                 IF comand$ = "1" THEN clr = 15 ELSE clr = 1
  263.                                 PSET (drawx, Structure.Image_Height - drawy), clr
  264.                                 drawx = drawx + 1: IF drawx > Structure.Image_Width - 1 AND drawx MOD 32 = 0 THEN drawx = 0: drawy = drawy + 1
  265.                             NEXT
  266.                         NEXT
  267.  
  268.                     CASE 16
  269.                         SEEK #1, Structure.Offset_from_begin + 817 'i have none informations about file area between color palette record and image data record...
  270.  
  271.                         GET #1, , A$
  272.                         A$ = LEFT$(A$, Structure.Image_Width * Structure.Image_Height)
  273.                         LoadCursor& = _NEWIMAGE(Structure.Image_Width + 12, Structure.Image_Height + 5, 256) '
  274.                         _DEST LoadCursor&
  275.                         _PALETTECOLOR 15, _RGB32(Mask.Rf, Mask.Gf, Mask.Bf)
  276.                         _PALETTECOLOR 1, _RGB32(Mask.Rb, Mask.Gb, Mask.Bb)
  277.                         _CLEARCOLOR 1, LoadCursor&
  278.  
  279.                         drawx = -3: drawy = -4 'Structure.Vertical
  280.                         FOR CursorDraw = 1 TO LEN(A$)
  281.                             bod = ASC(A$, CursorDraw)
  282.                             Bin$ = DECtoBIN$(bod)
  283.                             FOR drr = 1 TO LEN(Bin$)
  284.                                 comand$ = MID$(Bin$, drr, 1)
  285.                                 IF comand$ = "1" THEN clr = 15 ELSE clr = 1
  286.                                 PSET (drawx, Structure.Image_Height - drawy), clr
  287.                                 drawx = drawx + 1: IF drawx > Structure.Image_Width AND drawx MOD 32 = 0 THEN drawx = 0: drawy = drawy + 1
  288.                             NEXT
  289.                         NEXT
  290.                 END SELECT
  291.             END IF
  292.         NEXT ' color palette settings
  293.  
  294.     ELSE LoadCursor& = 1: EXIT FUNCTION 'if file not exists
  295.     END IF
  296.     IF Structure.Image_Color_Palette = 0 THEN _SETALPHA 0, _RGB32(0, 0, 0), cursor&
  297.     CLOSE #1
  298.     _DEST 0
  299.  
  300. FUNCTION DECtoBIN$ (vstup)
  301.     FOR rj = 7 TO 0 STEP -1
  302.         IF vstup AND 2 ^ rj THEN DECtoBIN$ = DECtoBIN$ + "1" ELSE DECtoBIN$ = DECtoBIN$ + "0"
  303.     NEXT rj
  304.  
  305. FUNCTION BINtoDEC (b AS STRING)
  306.     FOR Si = 1 TO LEN(b)
  307.         e$ = MID$(b$, Si, 1)
  308.         c = VAL(e$) '
  309.         Sj = LEN(b) - Si
  310.         BINtoDEC = BINtoDEC + (c * 2 ^ Sj)
  311.     NEXT Si
  312.  
  313.     IF INSTR(_OS$, "WINDOWS") THEN WIN = 1 ELSE WIN = 0
  314.  
  315. FUNCTION LastPos (bases AS STRING, search AS STRING)
  316.     FOR e = LEN(bases) TO 1 STEP -1
  317.         IF ASC(bases, e) = ASC(search) THEN LastPos = e + 1: EXIT FUNCTION
  318.     NEXT e
  319.