Linux cross compiles Windows applications PC Sof...


Welcome, Guest. Please login or register.
Username:   Password:

Hosted in the Cloud RSS

Recent Topics

Gallery Latest


535 Views
0 comment(s)

516 Views
0 comment(s)


851 Views
0 comment(s)

688 Views
0 comment(s)


557 Views
0 comment(s)

568 Views
1 comment(s)

Search The Gallery

User Info

Welcome, Guest. Please login or register.
July 25, 2017, 11:45:04 AM

Login with username, password and session length

Forum
Web
Gallery
Search:         Keywords:

   

DatahopaForumComputer RelatedPC Software Linux cross compiles Windows applications



Pages: [1]

Linux cross compiles Windows applications

Viewing: 0 Members and 1 Guest       Total Views: 1316

Offline 8pla.net Topic starter
United States WWW Posts: 154
Rank: Apprentice Adept

Linux, believe it or not, compiles Microsoft Windows graphical user interface (GUI) applications.
And, Linux executes these Microsoft Windows applications under WINE once they are complied.
This is what is known as cross compiling, which is the topic of this discussion thread.
Posted March 29, 2016, 02:34:17 AM Logged
My Very Enormous Monster Just Stopped Using Nine

Offline 8pla.net Topic starter
United States WWW Posts: 154
Rank: Apprentice Adept

Cross Compiler

Simple Windows program, written in C Language and the Win32 API.  Compiled on Linux.  
Running under WINE in Linux.  Notice the little WINE icon (top, left corner)?  

Code:
#include <windows.h>
int main(int argc, char *argv[])
{
        MessageBox(NULL,"Compile!","Cross",MB_ICONINFORMATION);
return 0;
}

Not to be confused a Linux program, this program will run on a Windows machine.



crosscompile.png
Linux cross compiles Windows applications
* crosscompile.png (42.11 KB, 411x351 - viewed 189 times.)
Posted March 29, 2016, 02:47:31 AM Logged
My Very Enormous Monster Just Stopped Using Nine

Offline DaveMorton
United States WWW Global Moderator
Posts: 2509
Rank: Certified
Comfort the Disturbed! Disturb the Comfortable!

Interesting. But the WIN32 API has been available to *nix platforms for several years now. I'm waiting for the day that modern Windows apps can be compiled to run in WINE's successor, but I don't see that happening any time soon. Smiley
Posted March 30, 2016, 20:59:52 PM Logged
Safe, Reliable Insanity, Since 1961!
Chat With Morti!

CAPTCHA4us

Offline 8pla.net Topic starter
United States WWW Posts: 154
Rank: Apprentice Adept

Hi Dave,

Correct me if I am wrong, but any Windows computer with less than a Core 2 Duo is Win32.
It won't use the full 64bit registers, but it's still plenty good enough.  I wonder if it is still true
that more things run on 32bit than 64bit?

I'm investigating rolling back from .NET C# to Win32 C Language, to build an entry for the
Loebner Prize Contest.  This is not a perfect demonstration, but it shows how source code
found on the web, may be compiled with a cross compiler.

Code:
/*  
   Credit to: Log Window Test App - by Napalm
   http://www.rohitab.com/discuss/topic/36060-c-win32-gui-example-programs/
   You may use all or any part of the following code as long as you agree
   to the Creative Commons Attribution 2.0 UK: England & Wales license.
   http://creativecommons.org/licenses/by/2.0/uk/

   Original source code modified 4/1/16 to simplify a demonstration of how
   Windows source code may be cross compiled on Linux, to run on Windows.  
*/

#include <windows.h>
#include <shlwapi.h>
  
// Child Window/Control IDs
#define IDC_TXTENTRY            100
#define IDC_TXTLOG              101
#define IDC_BTNADDENTRY         102
 
// Globals
HINSTANCE g_hInst;
HFONT g_hfText;
 
 
 
// I created this to change the default properties of how edit controls behave
// when accessed by the dialog manager.
LRESULT CALLBACK SubclassEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    WNDPROC wpOld = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    LRESULT lrResult = 0;
 
    if(wpOld){
        switch(uMsg)
        {
            // Last message to a window so we de-subclass ourselves.
            case WM_NCDESTROY:
                SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)wpOld);
                SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
                break;
 
            // Sent by IsDialogMessage() API to determine what keys the control wants.
            // We use this to forward the tab key so it selects the next control.
            case WM_GETDLGCODE:
                lrResult = CallWindowProc(wpOld, hWnd, uMsg, wParam, lParam);
                lrResult &= ~(DLGC_HASSETSEL | DLGC_WANTTAB);
                if(lParam && ((LPMSG)lParam)->message == WM_KEYDOWN &&
                    ((LPMSG)lParam)->wParam == VK_TAB)
                    lrResult &= ~DLGC_WANTMESSAGE;
                return lrResult;
        }
 
        // Call the original window procedure.
        return CallWindowProc(wpOld, hWnd, uMsg, wParam, lParam);
    }
 
    // Crap couldn't find the original window procedure... use default.
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // We should not have used a static.. we should really attach this value to the window
    // using either GWL_USERDATA or a allocated structure with a a pointer stored in GWL_USERDATA.
    static HWND s_hWndLastFocus;
 
    switch(uMsg)
    {
        // Initialize our window and create our child controls.
        case WM_CREATE:
            {
                HWND hWndChild;
                TCHAR szBuffer[MAX_PATH];
 
                hWndChild = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, NULL,
                    ES_AUTOHSCROLL | WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                    0, 0, 0, 0, hWnd, (HMENU)IDC_TXTENTRY, g_hInst, NULL);
                if(!hWndChild) return -1;
                // Subclass the edit control.
                SetWindowLongPtr(hWndChild, GWLP_USERDATA, GetWindowLongPtr(hWndChild, GWLP_WNDPROC));
                SetWindowLongPtr(hWndChild, GWLP_WNDPROC, (LONG_PTR)SubclassEditProc);
                // Set the edit controls properties.
                SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
                SendMessage(hWndChild, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0);

                SetFocus(hWndChild);
                s_hWndLastFocus = NULL;


                // Create a 'Chat' button.
                hWndChild = CreateWindowEx(0, WC_BUTTON, TEXT("&Chat"),
                    BS_PUSHBUTTON | BS_TEXT |
                    WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                    0, 0, 0, 0, hWnd, (HMENU)IDC_BTNADDENTRY, g_hInst, NULL);
                if(!hWndChild) return -1;
                // Set the button controls properties.
                SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);

                // Create 'log window' multi-line edit control.
                hWndChild = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, NULL,
                    ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_NOHIDESEL |
                    WS_VSCROLL | WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                    0, 0, 0, 0, hWnd, (HMENU)IDC_TXTLOG, g_hInst, NULL);
                if(!hWndChild) return -1;
                // Subclass the edit control.
                SetWindowLongPtr(hWndChild, GWLP_USERDATA, GetWindowLongPtr(hWndChild, GWLP_WNDPROC));
                SetWindowLongPtr(hWndChild, GWLP_WNDPROC, (LONG_PTR)SubclassEditProc);
                // Set the edit controls properties.
                SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
                SendMessage(hWndChild, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0);                
            }
            return 0;
 
        // We get this message with WA_INACTIVE set when our window is no-longer
        // the foreground window so we want to save which of our controls has the focus
        // so that when the user returns the right control gets the keyboard input.
        case WM_ACTIVATE:
            if(LOWORD(wParam) == WA_INACTIVE)
                s_hWndLastFocus = GetFocus();
            return 0;
 
        // We get this message when our window receives the user focus. We then
        // move that focus to the previously used child window.
        case WM_SETFOCUS:
            if(s_hWndLastFocus)
                SetFocus(s_hWndLastFocus);
            return 0;
 
        // We accept this message so we can set a minimum window size. This only sets the users
        // tracking size. The window itself can always be resized smaller programmatically unless
        // you restrict it in WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED.
        case WM_GETMINMAXINFO:
            {
                LPMINMAXINFO lpInfo = (LPMINMAXINFO)lParam;
                if(lpInfo)
                    lpInfo->ptMinTrackSize.x = 350, lpInfo->ptMinTrackSize.y = 280;
            }
            return 0;
 
        // These next two messages are better to use rather than WM_MOVE/WM_SIZE.
        // Remember WM_MOVE/WM_SIZE are from 16bit windows. In 32bit windows the window
        // manager only sends these two messages and the DefWindowProc() handler actually
        // accepts them and converts them to WM_MOVE/WM_SIZE.
        //
        // We accept this so we can scale our controls to the client size.
        case WM_WINDOWPOSCHANGING:
        case WM_WINDOWPOSCHANGED:
            {
                HDWP hDWP;
                RECT rc;
 
                // Create a deferred window handle.
                if(hDWP = BeginDeferWindowPos(5)){ // Deferring 5 child controls
                    GetClientRect(hWnd, &rc);
 
                    // Defer each window move/size until end and do them all at once.
                    hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_TXTENTRY), NULL,
                        10, 10, rc.right - 130, 25,
                        SWP_NOZORDER | SWP_NOREDRAW);
 
                    hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_BTNADDENTRY), NULL,
                        rc.right - 110, 10, 100, 25,
                        SWP_NOZORDER | SWP_NOREDRAW);

                    hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_TXTLOG), NULL,
                        10, 70, rc.right - 20, rc.bottom - 80,
                        SWP_NOZORDER | SWP_NOREDRAW);
 
                    // Resize all windows under the deferred window handled at the same time.
                    EndDeferWindowPos(hDWP);
 
                    // We told DeferWindowPos not to redraw the controls so we can redraw
                    // them here all at once.
                    RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN |
                        RDW_ERASE | RDW_NOFRAME | RDW_UPDATENOW);
                }
            }
            return 0;
 
        // Handle the notifications of button presses.
        case WM_COMMAND:
            // If it was a button press and came from our button.
            if(wParam == MAKELONG(IDC_BTNADDENTRY, BN_CLICKED)){
 
                INT nSelStart, nSelEnd;
                SCROLLINFO siLogVert;
                HWND hWndChild;
                LPTSTR lpBuffer;
                INT cchTextLen;
 
                // Allocate a buffer for our entry text.
                // The +2 is for an extra space we append and null terminator.
                hWndChild  = GetDlgItem(hWnd, IDC_TXTENTRY);
                cchTextLen = GetWindowTextLength(hWndChild);
                lpBuffer   = (LPTSTR)HeapAlloc(GetProcessHeap(),
                    HEAP_ZERO_MEMORY, (cchTextLen + 2) * sizeof(TCHAR));
                if(lpBuffer == NULL){
                    MessageBeep(MB_ICONERROR);
                    return 0;
                }
 
                // Read our entry text.
                if(GetWindowText(hWndChild, lpBuffer, cchTextLen + 1)){
                    StrCat(lpBuffer, TEXT("\n"));
 
                    // Get our edit log window handle.
                    hWndChild = GetDlgItem(hWnd, IDC_TXTLOG);
 
                    // Tell edit control not to update the screen.
                    SendMessage(hWndChild, WM_SETREDRAW, FALSE, 0);
 
                    // Save our current selection.
                    nSelStart = nSelEnd = 0;
                    SendMessage(hWndChild, EM_GETSEL, (WPARAM)&nSelStart, (LPARAM)&nSelEnd);
 
                    // Save our current scroll info.
                    ZeroMemory(&siLogVert, sizeof(SCROLLINFO));
                    siLogVert.cbSize = sizeof(SCROLLINFO);
                    siLogVert.fMask  = SIF_PAGE | SIF_POS | SIF_RANGE;
                    GetScrollInfo(hWndChild, SB_VERT, &siLogVert);

                    // Update the log window by appending text to it.
                    cchTextLen = GetWindowTextLength(hWndChild);
                    SendMessage(hWndChild, EM_SETSEL, cchTextLen, cchTextLen);
                    SendMessage(hWndChild, EM_REPLACESEL, FALSE, (LPARAM)lpBuffer);
 
                        // Restore scroll position if not pinned.
                        SendMessage(hWndChild, WM_VSCROLL, MAKELONG(siLogVert.nPos,
                            SB_THUMBPOSITION), 0);
                    // Restore old text selection.
                    SendMessage(hWndChild, EM_SETSEL, nSelStart, nSelEnd);
 
                    // Update the state of the edit control on the screen.
                    SendMessage(hWndChild, WM_SETREDRAW, TRUE, 0);
                    UpdateWindow(hWndChild);
 
                }else{
                    // No text in the entry box?
                    MessageBeep(MB_ICONWARNING);
                }
 
                // Free temporary entry box allocation.
                HeapFree(GetProcessHeap(), 0, lpBuffer);
                return 0;
            }
            break;
 
        case WM_DESTROY:
            // We post a WM_QUIT when our window is destroyed so we break the main message loop.
            PostQuitMessage(0);
            break;
    }
 
    // Not a message we wanted? No problem hand it over to the Default Window Procedure.
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
 
// Program Entry Point
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, INT nShowCmd)
{
    OSVERSIONINFO lpVer;
    WNDCLASSEX wcex;
    DWORD dwExStyle;
    HDC hdcScreen;
    HWND hWnd;
    MSG msg;
 
    g_hInst = hInst;
  
    ZeroMemory(&msg,  sizeof(MSG));
    ZeroMemory(&wcex, sizeof(WNDCLASSEX));
 
    // Register our Main Window class.
    wcex.cbSize     = sizeof(WNDCLASSEX);
    wcex.hInstance   = hInst;
    wcex.lpszClassName = TEXT("MainWindow");
    wcex.lpfnWndProc   = MainWindowProc;
    wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcex.hIcon       = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hIconSm       = wcex.hIcon;
    wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    if(!RegisterClassEx(&wcex))
        return 1;
 
    // Create a font we can later use on our controls.
    hdcScreen = GetDC(HWND_DESKTOP);
    g_hfText = CreateFont(-MulDiv(11, GetDeviceCaps(hdcScreen, LOGPIXELSY), 72), // 11pt
        0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS,
        CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, TEXT("Tahoma"));
    ReleaseDC(HWND_DESKTOP, hdcScreen);
 
    // Default main window ex-style.
    dwExStyle = WS_EX_APPWINDOW;
 
    // If we are using XP or above lets 'double-buffer' the window to reduce the
    // flicker to the edit controls when drawing (notepad needs this).
    lpVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if(GetVersionEx(&lpVer) && (lpVer.dwMajorVersion > 5 ||
        (lpVer.dwMajorVersion == 5 && lpVer.dwMinorVersion == 1)))
        dwExStyle |= WS_EX_COMPOSITED;
 
    // Create an instance of the Main Window.
    hWnd = CreateWindowEx(dwExStyle, wcex.lpszClassName, TEXT("Windows Chatbot Interface"),
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 450, 330,
        HWND_DESKTOP, NULL, hInst, NULL);
 
    if(hWnd){
        // Show the main window and enter the message loop.
        ShowWindow(hWnd, nShowCmd);
        UpdateWindow(hWnd);
        while(GetMessage(&msg, NULL, 0, 0))
        {
            // If the message was not wanted by the Dialog Manager dispatch it like normal.
            if(!IsDialogMessage(hWnd, &msg)){
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
 
    // Free up our resources and return.
    DeleteObject(g_hfText);
    return (int)msg.wParam;
}

Link to license: http://creativecommons.org/licenses/by/2.0/uk/
Credit to: Napalm.  Original Title: Log Window Test App. Originally Written: 2010
http://www.rohitab.com/discuss/topic/36060-c-win32-gui-example-programs/
Screenshot of modified version:  (See image attached below)


crosscompiled.png
Linux cross compiles Windows applications
* crosscompiled.png (9.04 KB, 472x354 - viewed 182 times.)
Posted April 02, 2016, 05:51:11 AM Logged
My Very Enormous Monster Just Stopped Using Nine
Pages: [1]
Jump to:  

Site Activity
Most Online Today: 171
150 Guests, 3 Users
Carl2, Data, Urania

fast-registration