Alpha Software Mobile Development Tools:   Alpha Anywhere    |   Alpha TransForm subscribe to our YouTube Channel  Follow Us on LinkedIn  Follow Us on Twitter  Follow Us on Facebook

Announcement

Collapse

The Alpha Software Forum Participation Guidelines

The Alpha Software Forum is a free forum created for Alpha Software Developer Community to ask for help, exchange ideas, and share solutions. Alpha Software strives to create an environment where all members of the community can feel safe to participate. In order to ensure the Alpha Software Forum is a place where all feel welcome, forum participants are expected to behave as follows:
  • Be professional in your conduct
  • Be kind to others
  • Be constructive when giving feedback
  • Be open to new ideas and suggestions
  • Stay on topic


Be sure all comments and threads you post are respectful. Posts that contain any of the following content will be considered a violation of your agreement as a member of the Alpha Software Forum Community and will be moderated:
  • Spam.
  • Vulgar language.
  • Quotes from private conversations without permission, including pricing and other sales related discussions.
  • Personal attacks, insults, or subtle put-downs.
  • Harassment, bullying, threatening, mocking, shaming, or deriding anyone.
  • Sexist, racist, homophobic, transphobic, ableist, or otherwise discriminatory jokes and language.
  • Sexually explicit or violent material, links, or language.
  • Pirated, hacked, or copyright-infringing material.
  • Encouraging of others to engage in the above behaviors.


If a thread or post is found to contain any of the content outlined above, a moderator may choose to take one of the following actions:
  • Remove the Post or Thread - the content is removed from the forum.
  • Place the User in Moderation - all posts and new threads must be approved by a moderator before they are posted.
  • Temporarily Ban the User - user is banned from forum for a period of time.
  • Permanently Ban the User - user is permanently banned from the forum.


Moderators may also rename posts and threads if they are too generic or do not property reflect the content.

Moderators may move threads if they have been posted in the incorrect forum.

Threads/Posts questioning specific moderator decisions or actions (such as "why was a user banned?") are not allowed and will be removed.

The owners of Alpha Software Corporation (Forum Owner) reserve the right to remove, edit, move, or close any thread for any reason; or ban any forum member without notice, reason, or explanation.

Community members are encouraged to click the "Report Post" icon in the lower left of a given post if they feel the post is in violation of the rules. This will alert the Moderators to take a look.

Alpha Software Corporation may amend the guidelines from time to time and may also vary the procedures it sets out where appropriate in a particular case. Your agreement to comply with the guidelines will be deemed agreement to any changes to it.



Bonus TIPS for Successful Posting

Try a Search First
It is highly recommended that a Search be done on your topic before posting, as many questions have been answered in prior posts. As with any search engine, the shorter the search term, the more "hits" will be returned, but the more specific the search term is, the greater the relevance of those "hits". Searching for "table" might well return every message on the board while "tablesum" would greatly restrict the number of messages returned.

When you do post
First, make sure you are posting your question in the correct forum. For example, if you post an issue regarding Desktop applications on the Mobile & Browser Applications board , not only will your question not be seen by the appropriate audience, it may also be removed or relocated.

The more detail you provide about your problem or question, the more likely someone is to understand your request and be able to help. A sample database with a minimum of records (and its support files, zipped together) will make it much easier to diagnose issues with your application. Screen shots of error messages are especially helpful.

When explaining how to reproduce your problem, please be as detailed as possible. Describe every step, click-by-click and keypress-by-keypress. Otherwise when others try to duplicate your problem, they may do something slightly different and end up with different results.

A note about attachments
You may only attach one file to each message. Attachment file size is limited to 2MB. If you need to include several files, you may do so by zipping them into a single archive.

If you forgot to attach your files to your post, please do NOT create a new thread. Instead, reply to your original message and attach the file there.

When attaching screen shots, it is best to attach an image file (.BMP, .JPG, .GIF, .PNG, etc.) or a zip file of several images, as opposed to a Word document containing the screen shots. Because Word documents are prone to viruses, many message board users will not open your Word file, therefore limiting their ability to help you.

Similarly, if you are uploading a zipped archive, you should simply create a .ZIP file and not a self-extracting .EXE as many users will not run your EXE file.
See more
See less

Example DLL translation from VBA into Xbasic

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #31
    RE: Example DLL translation from VBA into Xbasic

    Yes, you are right.
    Marcel

    I hear and I forget. I see and I remember. I do and I understand.
    ---- Confusius ----

    Comment


      #32
      RE: Example DLL translation from VBA into Xbasic

      Hi,

      I'm still working on some API stuff and naturally some strange things happens. Murphy is sitting on my shoulder ;-)

      One strange thing is that the order of the declare's make sometimes a big difference between a succesfull run or crash of the code.

      For instance, I have created some succesfull running code. When I add a new API-function to the code, in this case the declare for LocalAlloc, another function which ran before successfull now crashes. But when I move the declare statement to the top of the program the code will run successfull???? It's a complete riddle for me. And it does not always happen. There is no rule in this.

      What can make this happen?

      Second strange behaviour is that I have to start A5 from scratch every time when this kind of error occurs. That does mean in my opinion that the memory environment of A5 is disturbed and need to be reinitialized. I use the undeclare statements for the used functions at the end.

      Here a part of the code I'm talking about.

      Code:
      .
      .
      .
      declare KERNEL32 LocalAlloc LLL    'this was moved upwards
      declare KERNEL32 LocalFree LL
      declarestruct _MESSAGE C128message
      declare KERNEL32 FormatMessage@FormatMessageA LLLLL(_MESSAGE)LL
      declarestruct _FILENAME C260filename
      declarestruct _FILENAMEA C14filenameA
      .
      .
      .
      Regards,

      Marcel
      Marcel

      I hear and I forget. I see and I remember. I do and I understand.
      ---- Confusius ----

      Comment


        #33
        RE: Example DLL translation from VBA into Xbasic

        Yes, I've also found that I have to exit Alpha Five frequently when developing code for calling DLLs. I haven't found the order of the declarations matters, but I haven't been thunderously successful in deciphering the ins and outs of declarestruct, either.
        - Peter

        Comment


          #34
          RE: Example DLL translation from VBA into Xbasic

          Marcel (and anyone else following this thread):
          I think I have discovered the key. One problem is that I don't think the Xbasic declaration of "short" works in a type statement. In C, the "short" is the same size as the "word": both are 2 bytes. A DWORD in C is 4 bytes, which is the same size as the Xbasic INTEGER in a TYPE statement.
          When translating from a Visual Basic program, you should realize that a VB Integer is 2 bytes and a VB "long" is 4 bytes.

          So one way around things is to create one's own types that are equivalent to SHORT and WORD.
          As an example, here is the C structure for DEVMODE taken from the Microsoft site:
          "pre"
          ' DEVMODE structure in Windows
          ' both character buffers have 32 characters

          typedef struct _devicemode {
          BCHAR dmDeviceName[CCHDEVICENAME];
          WORD dmSpecVersion;
          WORD dmDriverVersion;
          WORD dmSize;
          WORD dmDriverExtra;
          DWORD dmFields;
          union {
          struct {
          short dmOrientation;
          short dmPaperSize;
          short dmPaperLength;
          short dmPaperWidth;
          short dmScale;
          short dmCopies;
          short dmDefaultSource;
          short dmPrintQuality;
          };
          POINTL dmPosition;
          DWORD dmDisplayOrientation;
          DWORD dmDisplayFixedOutput;
          };

          short dmColor;
          short dmDuplex;
          short dmYResolution;
          short dmTTOption;
          short dmCollate;
          BYTE dmFormName[CCHFORMNAME];
          WORD dmLogPixels;
          DWORD dmBitsPerPel;
          DWORD dmPelsWidth;
          DWORD dmPelsHeight;
          union {
          DWORD dmDisplayFlags;
          DWORD dmNup;
          }
          DWORD dmDisplayFrequency;
          #if(WINVER "= 0x0400)
          DWORD dmICMMethod;
          DWORD dmICMIntent;
          DWORD dmMediaType;
          DWORD dmDitherType;
          DWORD dmReserved1;
          DWORD dmReserved2;
          #if (WINVER "= 0x0500) || (_WIN32_WINNT "= 0x0400)
          DWORD dmPanningWidth;
          DWORD dmPanningHeight;
          #endif
          #endif /* WINVER "= 0x0400 */
          } DEVMODE;
          "/pre"
          And taken from a Visual Basic site, the same structure looks like this:
          "pre"
          Type DEVMODE
          dmDeviceName As String * CCDEVICENAME
          dmSpecVersion As Integer
          dmDriverVersion As Integer
          dmSize As Integer
          dmDriverExtra As Integer
          dmFields As Long
          dmOrientation As Integer
          dmPaperSize As Integer
          dmPaperLength As Integer
          dmPaperWidth As Integer
          dmScale As Integer
          dmCopies As Integer
          dmDefaultSource As Integer
          dmPrintQuality As Integer
          dmColor As Integer
          dmDuplex As Integer
          dmYResolution As Integer
          dmTTOption As Integer
          dmCollate As Integer
          dmFormName As String * CCFORMNAME
          dmUnusedPadding As Integer
          dmBitsPerPel As Integer
          dmPelsWidth As Long
          dmPelsHeight As Long
          dmDisplayFlags As Long
          dmDisplayFrequency As Long
          End Type"/pre"
          So the final script to call the ChangeDisplaySettings dll in Windows from Xbasic reads like this, below. What I have done is to declare 2 structures of my own that are equal to the C 'word' and C 'short'. Wherever the C definition uses "short" I have used CSHORT, wherever the C definition lists a WORD I have used CWORD, and wherever the C definition uses a DWORD I have substituted INTEGER.

          "pre"
          declarestruct charbuf C32charbuf
          declarestruct CSHORT W1X
          declarestruct CWORD W1Y

          type DEVMODE
          dmDeviceName as charbuf
          dmSpecVersion as CWORD
          dmDriverVersion as CWORD
          dmSize as CWORD
          dmDriverExtra as CWORD
          dmFields as INTEGER

          dmOrientation as CSHORT
          dmPaperSize as CSHORT
          dmPaperLength as CSHORT
          dmPaperWidth as CSHORT
          dmScale as CSHORT
          dmCopies as CSHORT
          dmDefaultSource as CSHORT
          dmPrintQuality as CSHORT

          dmColor as CSHORT
          dmDuplex as CSHORT
          dmYResolution as CSHORT
          dmTTOption as CSHORT
          dmCollate as CSHORT
          dmFormName as charbuf
          dmLogPixels as CWORD
          dmBitsPerPel as INTEGER
          dmPelsWidth as INTEGER
          dmPelsHeight as INTEGER
          dmDisplayFlags as INTEGER
          dmDisplayFrequency as INTEGER
          dmICMMethod as INTEGER
          dmICMIntent as INTEGER
          dmMediaTYpe as INTEGER
          dmDitherTYpe as INTEGER
          dmReserved1 as INTEGER
          dmReserved2 as INTEGER
          dmPanningWidth as INTEGER
          dmPanningHeight as INTEGER
          end type


          declare USER32 EnumDisplaySettings@EnumDisplaySettingsA LLL(DEVMODE)
          declare USER32 ChangeDisplaySettings@ChangeDisplaySettingsA L(DEVMODE)L

          result=ui_dlg_box("Video",""%dlg%
          {lf};
          Select Video Resolution;
          {frame=1,2}
          (res:800 by 600);
          (res:1024 by 768);
          {lf};
          "OK" "Cancel";
          %dlg%)
          if result="Cancel" then
          end
          end if

          change_res(val(word(res,1," ")), val(word(res,3," ")))

          end

          function change_res(width as n, height as n)
          CONSTANT DM_PELSWIDTH = hex_to_dec("80000")
          constant DM_PELSHEIGHT = hex_to_dec("100000")
          CONSTANT DM_BITSPERPEL = hex_to_dec("40000")

          dim DevM as {DEVMODE}

          dim disp as n
          disp=1
          i=0
          while disp " 0
          disp= EnumDisplaySettings(0,i,DevM)
          i=i+1
          end while

          DevM.dmFields = DM_PELSWIDTH .or. DM_PELSHEIGHT .or. DM_BITSPERPEL
          DevM.dmPelsWidth = width
          DevM.dmPelsHeight = height
          DevM.dmSize=8126592
          DevM.dmbitsperpel=32
          DevM.dmDisplayFrequency=60
          b = ChangeDisplaySettings(DevM, 0)
          end function"/pre"

          Comment


            #35
            RE: Example DLL translation from VBA into Xbasic

            Hi,

            Peter Wayne wrote:
            -------------------------------
            Marcel (and anyone else following this thread):
            I think I have discovered the key.

            Great!

            One problem is that I don't think the Xbasic declaration of "short" works in a type statement.

            Yes, the type Short did not work either in my code.

            In C, the "short" is the same size as the "word": both are 2 bytes. A DWORD in C is 4 bytes, which is the same size as the Xbasic INTEGER in a TYPE statement.
            When translating from a Visual Basic program, you should realize that a VB Integer is 2 bytes and a VB "long" is 4 bytes.

            [b]Yes, I was aware of that, but still used the integer in A5, because the short didn't work and I got a kind of result back. However I could not check if the values I got back were correct[b]

            So one way around things is to create one's own types that are equivalent to SHORT and WORD.

            [b]Yes, a genius idea.[b]

            Peter, there is another problem in general to translating C structures. However, in your code this is correct "solved" by declaring one member of a union and not using the members. But what if you do have to access members that are part of a union. For example:

            In the C structure example, DEVMODE taken from the Microsoft site as you did there is an union. A union is a structure like construct and can hold just one member at the same time. So it contains OR the structure starting with dmOrientation ... dmPrintQuality OR structure POINTL OR dmDisplayOrientation OR dmDisplayFixedOutput. I'll put the members number before the line and the sizes in bytes behind it and lets count:

            Code:
            [...]
            DWORD dmFields; 
            union { 
            1 struct { 
              short dmOrientation; (2 bytes)
              short dmPaperSize; (2 bytes)
              short dmPaperLength; (2 bytes)
              short dmPaperWidth; (2 bytes)
              short dmScale; (2 bytes)
              short dmCopies; (2 bytes)
              short dmDefaultSource; (2 bytes)
             short dmPrintQuality; (2 bytes)
            }; 
            2 POINTL dmPosition; (structure 2 x long = 8 bytes)
            3 DWORD dmDisplayOrientation; (4 bytes)
            4 DWORD dmDisplayFixedOutput; (4 bytes)
            };
            [...]
            So, the biggest member of the union is member 1 and is 16 bytes, then POINTL with 8 bytes, then 4 bytes and again 4 bytes. You could easily make the error to translate this to Xbasic as:

            Code:
            Type POINTL
            	X as Integer (4 bytes)
            	Y as Integer (4 bytes)
            End type
            
            [...]
            dmFields as INTEGER 
            
            dmOrientation as CSHORT 
            dmPaperSize as CSHORT 
            dmPaperLength as CSHORT 
            dmPaperWidth as CSHORT 
            dmScale as CSHORT 
            dmCopies as CSHORT 
            dmDefaultSource as CSHORT 
            dmPrintQuality as CSHORT 
            
            dmPosition {POINTL} (structure 2 x long = 8 bytes)
            dmDisplayOrientation Integer (4 bytes)
            dmDisplayFixedOutput Integer (4 bytes)
            
            dmColor as CSHORT
            
            [...]
            And declaring a too large structure. But what then. In case of a union you have to declare the biggest member in this case: the part from dmOrientation up to dmPrintQuality. But what if the information saved in this area by the calling function is not the printer information but the POINTL structure because it is a screen. In that case you get 8 bytes back: DevM.dmPosition.X and DevM.dmPostion.Y. But you can't access them because your structure is build up with the member with name: dmOrientation CSHORT. So when you use DevM.dmOrientation.X as you would in Xbasic you get only the first two bytes back

            Code:
            The first line is a part of member 1.
            The second line are the bits and bytes.
            The thirth shows the bytes you need.
            
            |||||
            |12345678|12345678|12345678|12345678|12345678|12345678|12345678|12345678|
            |||
            To create DevM.dmPosition.X you would have to construct it from dmOrientation and dmPapersize as a MSB and a LSB with some arithmetic.

            We could also use dummy members. If the biggest member is 16 bytes long and we do have to access the values from the members DevM.dmPosition.X and DevM.dmPosition.X we can create the next structure. Keep in mind that the starting position of the the union is always the same, right after dmFields and the size must alway be 16 bytes long.

            Code:
            Type POINTL
            	X as Integer (4 bytes)
            	Y as Integer (4 bytes)
            End type
            
            [...]
            dmFields as INTEGER 
            
            dmPosition {POINTL} (structure 2 x long = 8 bytes)
            dmDisplayOrientation Integer (4 bytes and functions as a dummy)
            dmDisplayFixedOutput Integer (4 bytes and functions as a dummy)
            
            dmColor as CSHORT
            
            [...]
            In this case we have also 16 bytes but now we can access the DevM.dmPosition.X and DevM.dmPosition.X of structure POINTL. Danger! You can't access dmDisplayOrientation and
            dmDisplayFixedOutput as they function as a dummy and on these location stands rubbish.

            So if you would access all four members of the union you can copy the structure four times, give them all a different name and use them for their particular function, printer, POINTL, orientation or fixed output. As the Microsoft Platform SDK says: dmFields Specifies whether certain members of the DEVMODE structure have been initialized. If a member is initialized, its corresponding bit is set, otherwise the bit is clear. A driver supports only those DEVMODE members that are appropriate for the printer or display technology. So this fields prescribe the union members to use.

            ---------------- So far unions.

            Ok, back to your code. It works but still I have some questions about it. Questions arises from the text about the EnumDisplaySettings part lpDevMode:
            [out] Pointer to a DEVMODE structure into which the function stores information about the specified graphics mode. Before calling EnumDisplaySettings, set the dmSize member to sizeof(DEVMODE), and set the dmDriverExtra member to indicate the size, in bytes, of the additional space available to receive private driver data.

            How did you get the size 8126592 of dmSize since there is no sizeof() function?

            Again Peter nice work.

            Marcel
            Marcel

            I hear and I forget. I see and I remember. I do and I understand.
            ---- Confusius ----

            Comment


              #36
              RE: Example DLL translation from VBA into Xbasic

              Ehhh something wen wrong I think, second try..

              Hi,

              Peter Wayne wrote:
              -------------------------------
              Marcel (and anyone else following this thread):
              I think I have discovered the key.

              Great!

              One problem is that I don't think the Xbasic declaration of "short" works in a type statement.

              Yes, the type Short did not work either in my code.

              In C, the "short" is the same size as the "word": both are 2 bytes. A DWORD in C is 4 bytes, which is the same size as the Xbasic INTEGER in a TYPE statement.
              When translating from a Visual Basic program, you should realize that a VB Integer is 2 bytes and a VB "long" is 4 bytes.

              Yes, I was aware of that, but still used the integer in A5, because the short didn't work and I got a kind of result back. However I could not check if the values I got back were correct

              So one way around things is to create one's own types that are equivalent to SHORT and WORD.

              Yes, a genius idea.

              Peter, there is another problem in general to translating C structures. However, in your code this is correct "solved" by declaring one member of a union and not using the members. But what if you do have to access members that are part of a union. For example:

              In the C structure example, DEVMODE taken from the Microsoft site as you did there is an union. A union is a structure like construct and can hold just one member at the same time. So it contains OR the structure starting with dmOrientation ... dmPrintQuality OR structure POINTL OR dmDisplayOrientation OR dmDisplayFixedOutput. I'll put the members number before the line and the sizes in bytes behind it and lets count:

              Code:
              [...]
              DWORD dmFields; 
              union { 
              1 struct { 
                short dmOrientation; (2 bytes)
                short dmPaperSize; (2 bytes)
                short dmPaperLength; (2 bytes)
                short dmPaperWidth; (2 bytes)
                short dmScale; (2 bytes)
                short dmCopies; (2 bytes)
                short dmDefaultSource; (2 bytes)
               short dmPrintQuality; (2 bytes)
              }; 
              2 POINTL dmPosition; (structure 2 x long = 8 bytes)
              3 DWORD dmDisplayOrientation; (4 bytes)
              4 DWORD dmDisplayFixedOutput; (4 bytes)
              };
              [...]
              So, the biggest member of the union is member 1 and is 16 bytes, then POINTL with 8 bytes, then 4 bytes and again 4 bytes. You could easily make the error to translate this to Xbasic as:

              Code:
              Type POINTL
              	X as Integer (4 bytes)
              	Y as Integer (4 bytes)
              End type
              
              [...]
              dmFields as INTEGER 
              
              dmOrientation as CSHORT 
              dmPaperSize as CSHORT 
              dmPaperLength as CSHORT 
              dmPaperWidth as CSHORT 
              dmScale as CSHORT 
              dmCopies as CSHORT 
              dmDefaultSource as CSHORT 
              dmPrintQuality as CSHORT 
              
              dmPosition {POINTL} (structure 2 x long = 8 bytes)
              dmDisplayOrientation Integer (4 bytes)
              dmDisplayFixedOutput Integer (4 bytes)
              
              dmColor as CSHORT
              
              [...]
              And declaring a too large structure. But what then. In case of a union you have to declare the biggest member in this case: the part from dmOrientation up to dmPrintQuality. But what if the information saved in this area by the calling function is not the printer information but the POINTL structure because it is a screen. In that case you get 8 bytes back: DevM.dmPosition.X and DevM.dmPostion.Y. But you can't access them because your structure is build up with the member with name: dmOrientation CSHORT. So when you use DevM.dmOrientation.X as you would in Xbasic you get only the first two bytes back

              Code:
              The first line is a part of member 1.
              The second line are the bits and bytes.
              The thirth shows the bytes you need.
              
              |--dmOrientation--|---dmPapersize---|--dmPaperLength--|--dmPaperWidth---|
              |12345678|12345678|12345678|12345678|12345678|12345678|12345678|12345678|
              |--------DevM.dmPosition.X----------|----------DevM.dmPosition.X--------|
              To create DevM.dmPosition.X you would have to construct it from dmOrientation and dmPapersize as a MSB and a LSB with some arithmetic.

              We could also use dummy members. If the biggest member is 16 bytes long and we do have to access the values from the members DevM.dmPosition.X and DevM.dmPosition.X we can create the next structure. Keep in mind that the starting position of the the union is always the same, right after dmFields and the size must alway be 16 bytes long.

              Code:
              Type POINTL
              	X as Integer (4 bytes)
              	Y as Integer (4 bytes)
              End type
              
              [...]
              dmFields as INTEGER 
              
              dmPosition {POINTL} (structure 2 x long = 8 bytes)
              dmDisplayOrientation Integer (4 bytes and functions as a dummy)
              dmDisplayFixedOutput Integer (4 bytes and functions as a dummy)
              
              dmColor as CSHORT
              
              [...]
              In this case we have also 16 bytes but now we can access the DevM.dmPosition.X and DevM.dmPosition.X of structure POINTL. Danger! You can't access dmDisplayOrientation and
              dmDisplayFixedOutput as they function as a dummy and on these location stands rubbish.

              So if you would access all four members of the union you can copy the structure four times, give them all a different name and use them for their particular function, printer, POINTL, orientation or fixed output. As the Microsoft Platform SDK says: dmFields Specifies whether certain members of the DEVMODE structure have been initialized. If a member is initialized, its corresponding bit is set, otherwise the bit is clear. A driver supports only those DEVMODE members that are appropriate for the printer or display technology. So this fields prescribe the union members to use.

              ---------------- So far unions.

              Ok, back to your code. It works but still I have some questions about it. Questions arises from the text about the EnumDisplaySettings part lpDevMode:
              [out] Pointer to a DEVMODE structure into which the function stores information about the specified graphics mode. Before calling EnumDisplaySettings, set the dmSize member to sizeof(DEVMODE), and set the dmDriverExtra member to indicate the size, in bytes, of the additional space available to receive private driver data.

              How did you get the size 8126592 of dmSize since there is no sizeof() function?

              Again Peter nice work.

              Marcel
              Marcel

              I hear and I forget. I see and I remember. I do and I understand.
              ---- Confusius ----

              Comment


                #37
                RE: Example DLL translation from VBA into Xbasic

                SSShh.....Ok now in Word..see attachment.
                Marcel

                I hear and I forget. I see and I remember. I do and I understand.
                ---- Confusius ----

                Comment


                  #38
                  RE: Example DLL translation from VBA into Xbasic

                  Marcel,
                  You cannot create a union in Xbasic, but you can create alternate structures that hook into the DLL with an alias to the dll. Here is an example:
                  Code:
                  declarestruct charbuf C32charbuf
                  declarestruct CSHORT W1X
                  declarestruct CWORD W1Y
                  
                  type DEVMODE
                  	dmDeviceName as charbuf
                  	dmSpecVersion as CWORD
                  	dmDriverVersion as CWORD
                  	dmSize as CWORD
                  	dmDriverExtra as CWORD
                  	dmFields as INTEGER
                  
                  	dmOrientation as CSHORT
                  	dmPaperSize as CSHORT
                  	dmPaperLength as CSHORT
                  	dmPaperWidth as CSHORT
                  	dmScale as CSHORT
                  	dmCopies as CSHORT
                  	dmDefaultSource as CSHORT
                  	dmPrintQuality as CSHORT
                  	
                  	dmColor as CSHORT
                  	dmDuplex as CSHORT
                  	dmYResolution as CSHORT
                  	dmTTOption as CSHORT
                  	dmCollate as CSHORT
                  	dmFormName as charbuf
                  	dmLogPixels as CWORD
                  	dmBitsPerPel as INTEGER
                  	dmPelsWidth as INTEGER
                  	dmPelsHeight as INTEGER
                  	dmDisplayFlags as INTEGER
                  	dmDisplayFrequency as INTEGER
                  	dmICMMethod as INTEGER
                  	dmICMIntent as INTEGER
                  	dmMediaTYpe as INTEGER
                  	dmDitherTYpe as INTEGER
                  	dmReserved1 as INTEGER
                  	dmReserved2 as INTEGER
                  	dmPanningWidth as INTEGER
                  	dmPanningHeight as INTEGER
                  end type 
                  
                  type POINTL
                  	X as INTEGER
                  	Y as INTEGER
                  end type 
                  
                  type DEVMODA
                  	dmDeviceName as charbuf
                  	dmSpecVersion as CWORD
                  	dmDriverVersion as CWORD
                  	dmSize as CWORD
                  	dmDriverExtra as CWORD
                  	dmFields as INTEGER
                  
                  	dmPosition as POINTL
                  	dmDummy as POINTL	
                  	
                  	dmColor as CSHORT
                  	dmDuplex as CSHORT
                  	dmYResolution as CSHORT
                  	dmTTOption as CSHORT
                  	dmCollate as CSHORT
                  	dmFormName as charbuf
                  	dmLogPixels as CWORD
                  	dmBitsPerPel as INTEGER
                  	dmPelsWidth as INTEGER
                  	dmPelsHeight as INTEGER
                  	dmDisplayFlags as INTEGER
                  	dmDisplayFrequency as INTEGER
                  	dmICMMethod as INTEGER
                  	dmICMIntent as INTEGER
                  	dmMediaTYpe as INTEGER
                  	dmDitherTYpe as INTEGER
                  	dmReserved1 as INTEGER
                  	dmReserved2 as INTEGER
                  	dmPanningWidth as INTEGER
                  	dmPanningHeight as INTEGER
                  end type 
                  
                  declare USER32 EnumDisplaySettings@EnumDisplaySettingsA LLL(DEVMODE)
                  declare USER32 EnumDisplaySettingsAlt@EnumDisplaySettingsA LLL(DEVMODA)
                  
                  declare USER32 ChangeDisplaySettings@ChangeDisplaySettingsA L(DEVMODE)L
                  
                  dim DevM as {DEVMODE}
                  dim DevA as {DEVMODA}
                  
                  dlg=
                  {lf};
                  Select Video Resolution;
                  %str%	
                  
                  dim disp as n
                  disp=1
                  i=0 ; j=0
                  choices=""
                  while disp > 0 
                  	disp= EnumDisplaySettingsAlt(0,i,DevA)
                  	i=i+1
                  	if DevA.dmBitsPerPel>8 .and. DevA.dmPelsHeight>400 then
                  		j=j+1
                  		choices=choices+"(res:"+DevA.dmBitsPerPel+" bpp at "+DevA.dmPelsWidth+\
                  		" by "+DevA.dmPelsHeight+");"+crlf()
                  	end if
                  end while
                  dlg=dlg+crlf()+"{frame=1,"+j+"}"+crlf()+choices+
                  {lf};
                   ;
                  %str%	
                  result=ui_dlg_box("Supported Video Resolutions",dlg)
                  
                  if result="Cancel" then
                     end
                  end if
                  DevA.dmBitsPerPel=val(word(res,1," "))
                  DevA.dmPelsWidth = val(word(res,4," "))
                  DevA.dmPelsHeight= val(word(res,6," "))
                  
                  CONSTANT DM_PELSWIDTH = hex_to_dec("80000")
                  constant DM_PELSHEIGHT = hex_to_dec("100000")
                  CONSTANT DM_BITSPERPEL = hex_to_dec("40000")
                  	
                  DevA.dmFields = DM_PELSWIDTH .or. DM_PELSHEIGHT .or. DM_BITSPERPEL
                  	
                  DevA.dmDisplayFrequency=60
                  b = ChangeDisplaySettings(DevA, 0)
                  Conceivably, if I needed to use the function for a printer, I wwould call the EnumDisplaySettings(printer_dev,i,DevM)
                  instead of
                  EnumDisplaySettingsAlt(0,i,DevA)

                  As for the DevM.dmSize, it actually turned out not to be necessary. I got the value because it's the value that was returned when I called EnumDisplaySettings, but at least as
                  far as Xbasic is concerned, it's not necessary.

                  So far, this is a useful utility for the computer-challenged in my office, who can't figure out how to reset the screen resolution in Windows.
                  - Peter

                  Comment


                    #39
                    RE: Example DLL translation from VBA into Xbasic

                    Peter,

                    There is some confusion of tongues. You are right about unions when it comes to VB. But I use both, VB and C examples. The C examples are comming from the Microsoft 2003 SDK. I use this as my greatest resource. If someone wants to translate a C structure to VB he encounters the same problem with unions. As what I rough outlined and what you answered I know I'm going into the right direction. I try to create a kind of rule of tumbs for translating structures and code from C to Xbasic and VB to Xbasic.

                    Marcel
                    Marcel

                    I hear and I forget. I see and I remember. I do and I understand.
                    ---- Confusius ----

                    Comment

                    Working...
                    X