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

  • Marcel Kollenaar
    replied
    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

    Leave a comment:


  • Peter.Wayne
    replied
    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

    Leave a comment:


  • Marcel Kollenaar
    replied
    RE: Example DLL translation from VBA into Xbasic

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

    Leave a comment:


  • Marcel Kollenaar
    replied
    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

    Leave a comment:


  • Marcel Kollenaar
    replied
    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

    Leave a comment:


  • Peter.Wayne
    replied
    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"

    Leave a comment:


  • Peter.Wayne
    replied
    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

    Leave a comment:


  • Marcel Kollenaar
    replied
    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

    Leave a comment:


  • Marcel Kollenaar
    replied
    RE: Example DLL translation from VBA into Xbasic

    Yes, you are right.

    Leave a comment:


  • Peter.Wayne
    replied
    RE: Example DLL translation from VBA into Xbasic

    Aha. The issue is that the Xbasic integer is 4 bytes long, while the VB integer is 2 bytes long. The structure I came up with was just the right size to compensate, even though the individual elements of the structure make no sense between the display name and near the end where bits/pixel and height and width are stored.

    Leave a comment:


  • Peter.Wayne
    replied
    RE: Example DLL translation from VBA into Xbasic

    Marcel,

    I think the issue may be the sizes of variables in Xbasic and C. I think that the confusion arises because they each use the same words for different things. In that case, all I did was keep hacking away at the structure of DEVMODE until I got one where the width and height were in the right place.

    Thanks for your help on this one.
    Regards,
    Peter

    Leave a comment:


  • Marcel Kollenaar
    replied
    RE: Example DLL translation from VBA into Xbasic

    Hi Peter,

    Indeed, very strange but it works well on my Dell desktop. It need some backwards investigation as you said. The solution will be somewhere in the API text and is always a matter of reading...

    Thanks, I learned a lot because your example brought the solution to mine. I used the properties function to examine the structure. It works now.

    Regards,

    Marcel

    Leave a comment:


  • Peter.Wayne
    replied
    RE: Example DLL translation from VBA into Xbasic

    Well, Marcel, I got it to work, but I can't explain why.
    Here it goes, for my notebook, which supports 1024x768 or 800x600 mode with either 16 or 32 bits/pixel:
    Code:
    constant DISP_CHANGE_SUCCESSFUL	= 0
    constant DISP_CHANGE_RESTART	= 1
    constant DISP_CHANGE_BADFLAGS	= (-4)
    constant DISP_CHANGE_FAILED	= (-1)
    constant DISP_CHANGE_BADMODE	= (-2)
    constant DISP_CHANGE_NOTUPDATED	= (-3)
     
    declarestruct _charbuf C32charbuf
    
    
    
    type DEVMODE
    	dmDeviceName as _charbuf
    	dmSpecVersion as Integer
    	dmDriverVersion as Integer
    	dmSize as Integer
    	dmDriverExtra as Integer
    	dmFields as Integer
    	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
    	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
    
    change_res(800, 600)
    undeclare EnumDisplaySettings
    undeclare ChangeDisplaySettings
    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 displaymodes[100] as c
    	'debug(1)
    	dim disp as n
    	disp=1
    	i=0
    	while disp > 0 
    		disp= EnumDisplaySettings(0,i,DevM)
    		i=i+1
    		'displaymodes[i]=property_to_string(DevM)
    	end while
    '	for j=23 to i
    '		ui_msg_box(""+(j-1),displaymodes[j])
    '	next	
    	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)
    	ui_msg_box("b",""+b)
    end function
    As you can see I removed a number of elements from the C structure. Don't ask me why it works, because I don't know. Maybe at another time I can figure it out.

    Leave a comment:


  • Marcel Kollenaar
    replied
    RE: Example DLL translation from VBA into Xbasic

    The union in this structure is a|the problem. For a union is as many room reserverd as its largest member of the union. In case of the first union: the struct {..} is valid or dmPosition or dmDisplayOrientation or dmDisplayFixedOutput. Obvious the struct is the largest and if a short is 16 bit there must be room for 8 x 16 = 128 bits (16 bytes). So we must create a patchwork for this.

    The last part of the structure are conditional compiler directives and must be examined it may be part of the structure in our case.

    If I am wrong please correct me.

    Regards,

    Marcel

    Code:
    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;

    Leave a comment:


  • Marcel Kollenaar
    replied
    RE: Example DLL translation from VBA into Xbasic

    Hi Peter,

    Try this one....

    Code:
    'Date Created: 27-Jun-2004 07:55:33 PM
    'Last Updated: 28-Jun-2004 08:37:03 PM
    'Created By  :
    'Updated By  : 
    
    constant DISP_CHANGE_SUCCESSFUL	= 0
    constant DISP_CHANGE_RESTART	= 1
    constant DISP_CHANGE_BADFLAGS	= (-4)
    constant DISP_CHANGE_FAILED	= (-1)
    constant DISP_CHANGE_BADMODE	= (-2)
    constant DISP_CHANGE_NOTUPDATED	= (-3)
     
    declarestruct _charbuf C32charbuf
    declarestruct _charbufx C32charbufx
    
    'typedef struct _POINTL { 
    '  LONG x; 
    '  LONG y; 
    '} POINTL, *PPOINTL;
    
    type POINTL
    	x as I
    	y as I
    end type
    
    type DEVMODE
    	dmDeviceName as _charbuf
    	dmSpecVersion as Integer
    	dmDriverVersion as Integer
    	dmSize as Integer
    	dmDriverExtra as Integer
    	dmFields as Integer
    	dmOrientation as Integer
    	dmPaperSize as Integer
    	dmPaperLength as Integer 'added
    	dmPaperWidth as Integer
    	dmScale as Integer
    	dmCopies as Integer
    	dmDefaultSource as Integer
    	dmPrintQuality as Integer
    	dmPosition as {POINTL}
    	dmDisplayOrientation as Integer
    	dmDisplayFixedOutput as Integer
    	dmColor as Integer	
    	dmDuplex as Integer
    	dmYResolution as Integer
    	dmTTOption as Integer
    	dmCollate as Integer
    	dmFormName as _charbufx 
    	dmLogPixels as Integer
    	dmBitsPerPel as Integer
    	dmPelsWidth as Integer
    	dmPelsHeight as Integer
    	dmDisplayFlags as Integer
    	dmDisplayFrequency as Integer
    end type 
    
    'BOOL EnumDisplaySettings(
    '  LPCTSTR lpszDeviceName,  // display device
    '  DWORD iModeNum,          // graphics mode
    '  LPDEVMODE lpDevMode      // graphics mode settings
    ');
    declare USER32 EnumDisplaySettings@EnumDisplaySettingsA LLL(DEVMODE)
    
    'LONG ChangeDisplaySettings(
    '  LPDEVMODE lpDevMode,  // graphics mode
    '  DWORD dwflags         // graphics mode options
    '); 
    declare USER32 ChangeDisplaySettings@ChangeDisplaySettingsA L(DEVMODE)L
    
    change_res(800, 600)
    undeclare EnumDisplaySettings
    undeclare ChangeDisplaySettings
    end
    
    function change_res(width as n, height as n)
    	CONSTANT DM_PELSWIDTH = hex_to_dec("80000")
    	constant DM_PELSHEIGHT = hex_to_dec("100000")
    	
    	dim DevM as {DEVMODE}
    
    	dim displaymodes[100] as c
    	'debug(1)
    	dim disp as n
    	disp=1
    	i=0
    	while disp > 0 .and. i 
    		disp= EnumDisplaySettings(0,i,DevM)
    		i=i+1
    		displaymodes[i]=property_to_string(DevM)
    	end while
    	for j=1 to i
    		ui_msg_box(""+(j-1),displaymodes[j])
    	next	
    	DevM.dmFields = DM_PELSWIDTH .or. DM_PELSHEIGHT
    	DevM.dmPelsWidth = width
    	DevM.dmPelsHeight = height
    	b = ChangeDisplaySettings(DevM, 0)
    	ui_msg_box("b",""+b)
    end function
    My screen got black and came back with DISP_CHANGE_FAILED. This is a good start.

    Marcel

    Leave a comment:

Working...
X