none
HWND C++ vers C# (XFS Provider) RRS feed

  • Discussion générale

  • Bonjour à tous,

    Je viens solliciter votre aide à cause d'un problème que je n'arrive pas à résoudre:

    Je développe actuellement un driver C# qui communique avec un Service Provider XFS.

    Seulement voila, le service génère des évènement que je n'arrive pas à remonter via mon driver, le système est le suivant : on exécute une fonction qui enregistre un HWND par lequel le message est envoyé, seulement voila je n'arrive pas à trouver le moyen de recevoir le message.

    Voici la doc de la fonction en question :

    HRESULT WFSRegister( hService, dwEventClass, hWndReg )
    Enables event monitoring for the specified service by the specified window; all messages of the specified class(es) are sent to the window specified in the hWndReg parameter. 
    
    Parameters:
    HSERVICE hService
    Handle to the service provider as returned by WFSOpen or WFSAsyncOpen.
    
    DWORD dwEventClass
    The class(es) of events for which the application is registering.
    
    HWND hWndReg
    The window handle which is to be registered to receive the specified messages.

    J'ai donc essayé de récupérer les message via un Window.Form et un Wrapper de la fonction, voila le wrapper :

    [DllImport("MSXFS.dll", EntryPoint = "WFSRegister")]
    public static extern int WFSRegister(IntPtr hService, //HSERVICE
                                                  uint dwEventClass, //DWORD
                                                  IntPtr hWndReg); //HWND


    et voila comment j’appelle la fonction :

    oPanel.TextChanged += new EventHandler(FormTextChanged);
    
    oPanel.Show();
    
    iResultFunction = XFS_LibraryWrapper_XFSAPI.WFSRegister(iptrService,
                                                           (uint)XFS_LibraryWrapper_XFSAPI.XFS_EVENT_CLASS.EXECUTE_EVENTS,
                                                            oPanel.Handle);

    Alors au niveau des résultat, j'ai bien l'affichage de la fenêtre, j'ai bien un évènement de généré quand je change le texte de la fenêtre et j'ai bien l'evénement générer par le ServiceProvider, seulement lui il ne change pas le texte de la WinForm, et c'est la qu'est mon problème.

    Je suis preneur de toute pistes, en vous remerciant par avance.

    Cordialement

    • Type modifié Aurel Bera jeudi 1 novembre 2012 08:24 Pas de reponse
    lundi 29 octobre 2012 10:47

Toutes les réponses

  • Bonjour Cyril,

    Peux-tu nous indiquer plus de détail de la documentation (une url par ex.) Si Execute_Events correspond à un handle d'événement appelé, utilisez l'exemple que j'avais fourni sur votre précédent Thread.

     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    lundi 29 octobre 2012 15:45
  • En ce qui concerne l'ancienne exemple, je ne peux pas l'utiliser mon SP me remonte une erreur de Invalide Window Handle

    Voici toute la doc que j'ai à ma disposition

    4.11 Notification Mechanisms — Registering for Events
    The WFSRegister and WFSDeregister functions (and their asynchronous counterparts) are used to register and
    deregister the window procedures which are to receive Windows messages when particular unsolicited,
    asynchronous events occur, either during request processing or at other times. In other words, they are used to enable or disable the reception of event notifications. By providing notifications of this type to applications, the requirement to poll for status is removed, and a simple method for implementing "monitoring" applications is provided. Each WFSRegister call specifies a service handle (hService), one or more event classes, and an application window handle (hWnd) which is to receive all the messages of the specified class(es). The corresponding SPI functions, WFPRegister and WFPDeregister, implement the API functions.
    There are four classes of events:
     SERVICE_EVENTS
     USER_EVENTS
     SYSTEM_EVENTS
     EXECUTE_EVENTS
    For the first three of these event classes, if a class is being monitored and an event occurs in that class, a message is broadcast to every hWnd registered for that class, specifying the service identified by the hService handle. The exception to this is the WFS_SYSE_LOCK_REQUESTED system event, this event is posted only to the application which owns the lock on the device. The events are generated when: the service status changes (SERVICE_EVENTS), e.g., a printer is suspended or is no
    longer available.
    
     the service needs an operation from the user to take place (USER_EVENTS), e.g., a device needs “abnormal” attention, such as adding paper or toner to a printer.
     a system event occurs (SYSTEM_EVENTS), e.g., a hardware error occurs, a version negotiation fails, the network is no longer available or there is no more disk space.
    
    The EXECUTE_EVENTS class is different from the other three. These are events which occur as a normal part of processing an WFSExecute command and they are always sent before the completion of the command.
    
    Examples include the need to interact with the user or operator to request an action such as inserting a passbook into a printer, “swiping” a mag stripe card, etc. A message generated by one of these events is sent only to the application that issued the WFSExecute that caused the event, even though other applications are registered for EXECUTE_EVENTS. Note that an application must explicitly register for these events; if it has not, and such an event occurs, the event is not deliverable and the WFSExecute completes normally.
    
    The logic of WFSRegister is cumulative: for a given service the number of notification messages sent may be increased by specifying additional event classes. Since the XFS Manager does not keep track of what events the application is registered for and the logic of the register/deregister mechanism is cumulative, the service providers are responsible for implementing the logic of this process
    
    An application requests registration for more than one event class in a single call by using a logical ‘OR’:
    
    hr = WFSRegister( hService,USER_EVENTS|SERVICE_EVENTS,hWnd );
    
    Note that services always monitor their resources, regardless of whether any application has registered for event monitoring or not. Issuing WFSRegister simply causes a service to send notifications to the service provider, which, in turn, sends notifications to one or more applications.
    
    To communicate to the XFS Manager that it no longer wishes to receive messages in one or more event classes, an application can cancel any previous registration using the WFSDeregister function. The logic of WFSRegister and WFSDeregister is symmetric: the application can deregister one or more classes of events monitored for each window, by properly specifying them in the parameter list. To deregister completely (e.g., every event class for every window), an application uses NULL event class and window handle values in the parameter list.
    
    Although the WFSDeregister takes effect immediately, it is possible that messages may be waiting in the applications message queue. A robust application must therefore be prepared to receive event messages even after deregistration.
    
    Note that an event notification message always passes the information describing the event to an application by pointing to a WFSRESULT data structure. After the application has used the data in the structure, it must free the memory that the service provider allocated for the WFSRESULT data structure, using the WFSFreeResult
    function.

    Et la doc concernant la fonction :

    5.20 WFSRegister
    
    HRESULT WFSRegister( hService, dwEventClass, hWndReg )
    Enables event monitoring for the specified service by the specified window; all messages of the specified class(es) are sent to the window specified in the hWndReg parameter. 
    
    Parameters:
    
    HSERVICE hService
    Handle to the service provider as returned by WFSOpen or WFSAsyncOpen. If this value is NULL, and dwEventClass is SYSTEM_EVENTS, the XFS manager registers the application for those system events generated by the Manager itself.
    
    DWORD dwEventClass
    The class(es) of events for which the application is registering. Specified as a set of bit masks that are logically ORed together into this parameter.
    
    HWND hWndReg
    The window handle which is to be registered to receive the specified messages.
    
    Comments Issuing a WFSRegister for a service enables event monitoring on that service. WFSRegister calls can be cumulative for the same window. For example, to receive notification for both system and user events, the application can call WFSRegister with both SYSTEM_EVENTS
    and USER_EVENTS, as follows:
    
    hr = WFSRegister(hPassbook1, SYSTEM_EVENTS | USER_EVENTS, hWndReg1);
    or call them in two phases:
    
    hr = WFSRegister( hPassbook1, SYSTEM_EVENTS, hWndReg1);
    . . . . . . . .
    . . . . . . . .
    hr = WFSRegister( hPassbook1, USER_EVENTS, hWndReg1);
    
    To cancel notifications use WFSDeregister.
    Note that the service provider always monitors the service, regardless of whether an
    application has registered for event monitoring. Issuing WFSRegister simply causes the
    service provider to post messages to the application in addition to handling the messages itself.
    See the discussion in Section 3.11.
    
    Error Codes
    If the function return is not WFS_SUCCESS, it is one of the following error conditions.
    
    WFS_ERR_CANCELED
    The request was canceled by WFSCancelBlockingCall.
    
    WFS_ERR_CONNECTION_LOST
    The connection to the service is lost.
    
    WFS_ERR_INTERNAL_ERROR
    An internal inconsistency or other unexpected error occurred in the XFS subsystem.
    
    WFS_ERR_INVALID_EVENT_CLASS
    The dwEventClass parameter specifies one or more event classes not supported by the service.
    
    WFS_ERR_INVALID_HSERVICE
    The hService parameter is not a valid service handle.
    
    WFS_ERR_INVALID_HWNDREG
    The hWndReg parameter is not a valid window handle.
    
    WFS_ERR_NOT_STARTED
    The application has not previously performed a successful WFSStartUp.
    
    WFS_ERR_OP_IN_PROGRESS
    A blocking operation is in progress on the thread; only WFSCancelBlockingCall and WFSIsBlocking are permitted at this time.


    lundi 29 octobre 2012 17:00
  • Bonjour,

    Pouvez-vous mettre le handle de WinForm dans hWndReg1 au lieu du panel (this.Handle)?

    Ensuite, essayez de faire un Hook Windows Message comme suit :

    protected override void WndProc(ref Message m)
    {
         base.WndProc(ref m);
    }

    Il faut surcharger la méthode WndProc. D'après la doc cette partie va recevoir les codes erreurs cités dans votre doc WFS_ERR_CANCELED... Faites un Enum de ces codes avec le correspondance Hexa ou numérique selon votre doc.

    Votre code serait de la manière suivant :

    protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                switch (m.Msg)
                {
                    case WFSError.WFS_ERR_CANCELED:
                        //traitement de cancel etc
                        break;
                }
            }

    Ceci n'est qu'un exemple. Si vous avez des questions ou problème(s), n'hésitez pas à revenir.

     

    Cordialement




    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    lundi 29 octobre 2012 19:12
  • La gestion des erreurs est déjà implémenté et marche bien, mon gros problème vient du handle de window qui est censé récupérer l'évènement, voici le genre d’évènement qui est généré:

    6.6 WFS_EXEE_CIM_CASHUNITERROR
    Description This execute event specifies that in a  denominate or dispense command a cash unit was addressed which caused a problem.
    
    Event Param LPWFSCIMCUERROR lpCashUnitError;
    
    typedef struct _wfs_cim_cu_error
    {
    WORD wFailure;
    LPWFSCIMCASHIN lpCashUnit;
    } WFSCIMCUERROR, * LPWFSCIMCUERROR;
    
    wFailure
    Specifies the kind of failure that occurred in the cash unit. Values are:
    
    lpCashUnit
    Pointer to the cash unit structure that caused the problem. For a description of the WFSCIMCASHIN structure see the definition of the WFS_INF_CIM_CASH_UNIT_INFO command.
    

    Le oPanel est en fait ma winform:

    Form oPanel = new Form();

    Le nom est pas très explicite c'est vrai. Donc j'arrive bien à avoir ma fenêtre sauf que je ne récupère rien lors des évènement.

    mardi 30 octobre 2012 08:29
  • Pouvez-vous me faire part du code que vous avez fait SVP ?

    Est-ce que c'est cette partie que vous n'arrivez pas à implémenter ?

    Event Param LPWFSCIMCUERROR lpCashUnitError;

     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    mardi 30 octobre 2012 09:43
  • Voila le code : 

    public int InitProcessXFS(string strFunction, ref string strErrorMessage)
    {
       Form oPanel = new Form();
    
       oPanel.TextChanged += new EventHandler(FormTextChanged);
    
       oPanel.Show();
    
       iResultFunction = XFS_LibraryWrapper_XFSAPI.WFSRegister(iptrService,
                                                                                    (uint)XFS_LibraryWrapper_XFSAPI.XFS_EVENT_CLASS.EXECUTE_EVENTS
                                                                                    | (uint)XFS_LibraryWrapper_XFSAPI.XFS_EVENT_CLASS.SERVICE_EVENTS
                                                                                    | (uint)XFS_LibraryWrapper_XFSAPI.XFS_EVENT_CLASS.SYSTEM_EVENTS
                                                                                    | (uint)XFS_LibraryWrapper_XFSAPI.XFS_EVENT_CLASS.USER_EVENTS,
                                                                                    oPanel.Handle);
    }
    
    void FormTextChanged(object Sender, EventArgs e)
    {
         TraceEvent(TraceLevel.eTRACE_DEBUG, "EVENT", "FormTextChanged");
    }

    Si je change le texte manuellement j'ai bien ma trace de généré, et j'ai bien la preuve que l'événement de mon SP est généré mais je ne le récupère pas dans ma Form.


    mardi 30 octobre 2012 10:02
  • L'événement FormTextChanged ne sera appelé que par une action de changement coté .NET.

    WFSRegister ne connait pas l'événement FormTextChanged donc Il faut lui faire connaitre via un pointer. D'ailleurs l'événement doit être déclaré qu'une seule fois, à l'init de la fenêtre. Ensuite dans le code de votre fonction InitProcessXFS : si vous souhaitez afficher strErrorMessage, il suffit de faire oPanel.Text = strErrorMessage.

    Si c'est un WFSRegister qui appel un événement d'erreur, il faut le déclarer en pointer grâce à Marshal avec la même signature de déclaration fournit par la doc.

     

    Le mieux et d'avoir le source du code + la doc complète avec le code.

     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    mardi 30 octobre 2012 10:20
  • Bonjour,

    Nous changeons le type de votre question à « Discussion générale » parce que vous n’êtes pas revenu avec les informations sollicitées. Si vous avez plus de temps pour réexaminer la question et fournir plus d'informations, n'hésitez pas à modifier le type du thread à « Question ». Si le problème est résolu, s’il vous plaît partagez la solution avec nous afin que la réponse puisse être trouvée et utilisée par d'autres membres de la communauté ayant des questions similaires.

    Merci !

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    jeudi 1 novembre 2012 08:24