2008-01-26

Sending message to user

Following job illustrates how to send message to user in AX 3.0
static void JobSendMessage(Args _args)
{
    AOSSessionInfo  testSession;

    int             counter;
    int             maxSessions;

    container       users;
    int             sesId;
    userId          userId;
    ClientType      clientKind;
    date            logindate;
    int             logintime;
    str             clientComputerName;
    str             databaseSpid;
    str             itemSTr;
    userName        userName;
    AOSClientMode   clientMode;
    int             sessionCount;
    int             idleTicks;
    str             recipient = curuserid();// place here addressee userid
    int             recSesId = -1;
    ;

    [ users, maxSessions ] = SysUsersOnline::getAllOnlineUserInfo();
    for(counter = 1; counter <= maxSessions; counter++)
    {
        [   sesId,
            userId,
            clientKind,
            loginDate,
            loginTime,
            clientComputerName,
            databaseSpid,
            userName,
            clientMode,
            idleTicks
            ] = conPeek(users, counter);
            if(userId == recipient)             {                 recSesId = sesId;                 break;             }     }     if(recsesId != -1)     {         testSession = new AOSSessionInfo(recsesId);         if (testSession)         {             AOSSessionInfo::sendMessage(                recsesId, strfmt("@SYS55325", curuserid(), time2str(timenow(),0,0)),
                "Hello!");             box::info("Delievered");         }     }     else     {         throw error(strFmt("User %1 is offline.", recipient));     } }

Borrowed from \Menu Items\Action\SysUsersSendMessage
Involved classes:
\Classes\SysUsersSendMessage
\Classes\SysUsersOnline
Copyright © 2008 Ruslan Goncharov

2008-01-17

How to clarify what happened with variables in AX

In microsoft.public.axapta.programming group Arjang in subject "Finding the lookup table of a lookup field" asked how to find out what is the look up table used to display the values for SalesTable.SalesStatus filed.

I've suggested look at SalesTableType and SalesLineType classes. The next question was how did I pointed at these classes.

Unfortunately I can't reply in the newsgroup at the moment (something wrong with the newsgroup or my browser), so I've decided to answer here in my blog.

Actually in AOT you may find out a huge chunk of information about tables, classes, enumerations etc. In case of SalesTable.SalesStatus field first of all I've decided to look at SalesTable Methods AOT node (just clicked Search [SalesStatus]). Looking at table's methods we may get a lot of useful information.

The second step was the searching of SalesStatus text in Classes.

By the way don't forget about cross-references. The cross-reference is important tool when you develop or debug Dynamics Ax.

Copyright © 2008 Ruslan Goncharov

2008-01-12

How to get the screenshots of all open windows in AX

This job allows get screenshots of all currently open windows in Axapta. It based on idea published in How to get list of all open windows and their names in AX
static void JobAllTheWindowsScreenshots(Args _args)
{        
        #define.screenshotFolder('q:\\capture\\')

        hWnd Parent;
        hWnd handle;

        hWnd mdi;
        #WinApi

        dialog d = new Dialog();
        DialogTabPage dt;

        str text;

        // retrieves the visibility state of the specified window -->
        DLL _DLL = new DLL('USER32');
        DLLFunction _isWindowVisible = new DLLFunction(_DLL, 'IsWindowVisible');
        // retrieves the visibility state of the specified window <--

        container cHWnd;         int i;         void addTab()         {                 if(text)                 {                                       dt = d.addTabPage(text);                         d.addText(text);                         cHWnd+=handle;
                }         }         fileName getSaveName(identifiername name)         {                 return #screenshotFolder + name + ".bmp";         }         void captureForm()         {                 Image image = new Image();                 ;                 // Take a screenshoot of the form                 image.captureWindow(handle);                 // reduce the colors (bits/pixel)                 image.reduceColorOctree(FALSE,256);                 // Save it as bitmap                 image.saveImage(getSaveName(text), ImageSaveType::BMP_UNCOMP);         }         ;         d.caption("All the windows");         d.windowType(FormWindowType::PopUp);         Parent = infolog.hWnd();         mdi = WinApi::getWindow(Parent, #GW_CHILD);         handle = WinApi::getWindow(mdi, #GW_CHILD);         text = WinApi::getWindowText(handle);         addTab();         if(handle)         {                 while(handle)                 {                         handle = WinApi::getWindow(handle, #GW_HWNDNEXT);                         text = WinApi::getWindowText(handle);
                        addTab();                 }         }         // retrieves the visibility state of the specified window -->         _isWindowVisible.returns(ExtTypes::DWord);         _isWindowVisible.arg(ExtTypes::DWord);         // retrieves the visibility state of the specified window <--
        for(i=1; i<=conlen(cHWnd); i++)         {                 handle = conPeek(cHWnd, i);                 if( _isWindowVisible.call(handle) )                 {                         infolog.activateWindow(handle);                         WinApi::updateWindow(handle);                         text = strFmt('%1 %2', i, strRem(WinApi::getWindowText(handle), '\\/:*?"<>|'));                         captureForm();                 }
        }         d.run(); }  
Note #screenshotFolder definition sets the path to the folder where screenshot collection is storing, so you have to adjusting your path on you own.
Copyright © 2008 Ruslan Goncharov

2008-01-09

Lorenz attractor

The Lorenz attractor is a set of differential equations which are popular in the field of Chaos. Following job visualize Lorenz attractor:
static void JobLorenzAttractor(Args _args)
{
        #define.iterations(1000000)

        #define.sigma(5)
        #define.r(15)
        #define.b(1)

        #define.imageSizeX(300)
        #define.imageSizeY(300)

        Form            form;
        FormRun         formRun;
        FormDesign      formDesign;

        Args            args;
        FormBuildDesign formBuildDesign;

        FormBuildWindowControl formBuildWindowControl;
        FormWindowControl pane;

        Image image = new Image();

        void DrawAttractor()
        {
                real x, y, z;
                int color;

                real t;

                real x1, y1, z1;
                real dt;

                int _x, _y;
                ;

                color = 0xFF00;

                x = 3.051522;
                y = 1.582542;
                z = 15.62388;

                dt = 0.0001;

                for(t=0; t<#iterations; t++)
                {
                        x1 = x + #sigma*(y-x)*dt;
                        y1 = y + (#r*x-y-z*x)*dt;
                        z1 = z + (x*y-#b*z)*dt;
        
                        x = x1; y = y1; z = z1;

                        _x = 16*(y - x*0.292893) + 150;
                        _y =-13*(z + x*0.292893) + 330;

                        if((_x>0)&&(_x<#imageSizeX)&&(_y>0)&&(_y<#imageSizeY))
                        {
                                image.setPixel(_x,_y, color);// + (t div 1000));
                        }
                }
        }
        ;

        form = new Form();
        formBuildDesign = form.addDesign('design');
        formBuildDesign.hideToolbar(true);

        formBuildDesign.columns(1);
        formBuildDesign.topMode(1); // Auto
        formBuildDesign.leftMode(1); // Auto
        formBuildDesign.widthMode(1); // Auto
        formBuildDesign.heightMode(1); // Auto
        formBuildDesign.width(1.4*#imageSizeX);

        formBuildWindowControl = formBuildDesign.addControl(FormControlType::IMAGE, 'pane');
        formBuildWindowControl.height(#imageSizeY);
        formBuildWindowControl.width(#imageSizeX);
        formBuildWindowControl.backgroundColor(0);

        args = new Args();
        args.object(form);
        formRun = classFactory.formRunClass(args);
        formRun.init();
        formRun.resetSize();
        formDesign = formRun.design();
        formRun.resetSize();
        formrun.formOnTop();
        formRun.run();


        formRun.design().caption('Lorenz attractor');
        pane = formRun.control(formBuildWindowControl.id());

        image.saveType(ImageSaveType::BMP_UNCOMP);
        image.createImage(#imageSizeX, #imageSizeY, 24);
        DrawAttractor();         pane.image(image);         formRun.design().caption(strFmt('Lorenz attractor - sigma: %1, r: %2, b: %3, iterations: %4',                 #sigma, #r, #b, #iterations));         formRun.wait(); }
Note: in the job the number of iterations is equal one million by default, so it takes several minutes to see the result. You may change parameters sigma, r, b and iterations and enjoy the behaviour of attractor.
Copyright © 2008 Ruslan Goncharov