// pjsua_wince.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "pjsua_wince.h"
#include <commctrl.h>
#include <pjsua-lib/pjsua.h>

#define MAX_LOADSTRING 100

// Global Variables:
static HINSTANCE    hInst;
static HWND	    hMainWnd;
static HWND	    hwndCB;
static HWND	    hwndGlobalStatus, hwndURI, hwndCallStatus;
static HWND	    hwndActionButton, hwndExitButton;



//
// Basic config.
//
#define SIP_PORT	5060


//
// Destination URI (to make call, or to subscribe presence)
//
#define SIP_DST_URI	"sip:192.168.0.7:5061"

//
// Account
//
#define HAS_SIP_ACCOUNT	0	// 0 to disable registration
#define SIP_DOMAIN	"server"
#define SIP_REALM	"server"
#define SIP_USER	"user"
#define SIP_PASSWD	"secret"

//
// Outbound proxy for all accounts
//
#define SIP_PROXY	NULL
//#define SIP_PROXY	"sip:192.168.0.2;lr"


//
// Configure nameserver if DNS SRV is to be used with both SIP
// or STUN (for STUN see other settings below)
//
#define NAMESERVER	NULL
//#define NAMESERVER	"62.241.163.201"

//
// STUN server
#if 0
	// Use this to have the STUN server resolved normally
#   define STUN_DOMAIN	NULL
#   define STUN_SERVER	"stun.fwdnet.net"
#elif 0
	// Use this to have the STUN server resolved with DNS SRV
#   define STUN_DOMAIN	"iptel.org"
#   define STUN_SERVER	NULL
#else
	// Use this to disable STUN
#   define STUN_DOMAIN	NULL
#   define STUN_SERVER	NULL
#endif

//
// Use ICE?
//
#define USE_ICE		0


//
// Globals
//
static pj_pool_t   *g_pool;
static pj_str_t	    g_local_uri;
static int	    g_current_acc;
static int	    g_current_call = PJSUA_INVALID_ID;
static int	    g_current_action;

enum
{
    ID_GLOBAL_STATUS	= 21,
    ID_URI,
    ID_CALL_STATUS,
    ID_POLL_TIMER,
};

enum
{
    ID_MENU_NONE	= 64,
    ID_MENU_CALL,
    ID_MENU_ANSWER,
    ID_MENU_DISCONNECT,
    ID_BTN_ACTION,
};


// Forward declarations of functions included in this code module:
static ATOM		MyRegisterClass	(HINSTANCE, LPTSTR);
BOOL			InitInstance	(HINSTANCE, int);
static void		OnCreate	(HWND hWnd);
static LRESULT CALLBACK	WndProc		(HWND, UINT, WPARAM, LPARAM);



/////////////////////////////////////////////////////////////////////////////

static void OnError(const wchar_t *title, pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];
    PJ_DECL_UNICODE_TEMP_BUF(werrmsg, PJ_ERR_MSG_SIZE);

    pj_strerror(status, errmsg, sizeof(errmsg));
    
    MessageBox(NULL, PJ_STRING_TO_NATIVE(errmsg, werrmsg, PJ_ERR_MSG_SIZE),
	       title, MB_OK);
}


static void SetLocalURI(const char *uri, int len, bool enabled=true)
{
    wchar_t tmp[128];
    if (len==-1) len=pj_ansi_strlen(uri);
    pj_ansi_to_unicode(uri, len, tmp, PJ_ARRAY_SIZE(tmp));
    SetDlgItemText(hMainWnd, ID_GLOBAL_STATUS, tmp);
    EnableWindow(hwndGlobalStatus, enabled?TRUE:FALSE);
}



static void SetURI(const char *uri, int len, bool enabled=true)
{
    wchar_t tmp[128];
    if (len==-1) len=pj_ansi_strlen(uri);
    pj_ansi_to_unicode(uri, len, tmp, PJ_ARRAY_SIZE(tmp));
    SetDlgItemText(hMainWnd, ID_URI, tmp);
    EnableWindow(hwndURI, enabled?TRUE:FALSE);
}


static void SetCallStatus(const char *state, int len)
{
    wchar_t tmp[128];
    if (len==-1) len=pj_ansi_strlen(state);
    pj_ansi_to_unicode(state, len, tmp, PJ_ARRAY_SIZE(tmp));
    SetDlgItemText(hMainWnd, ID_CALL_STATUS, tmp);
}

static void SetAction(int action, bool enable=true)
{
    HMENU hMenu;

    hMenu = CommandBar_GetMenu(hwndCB, 0);

    RemoveMenu(hMenu, ID_MENU_NONE, MF_BYCOMMAND);
    RemoveMenu(hMenu, ID_MENU_CALL, MF_BYCOMMAND);
    RemoveMenu(hMenu, ID_MENU_ANSWER, MF_BYCOMMAND);
    RemoveMenu(hMenu, ID_MENU_DISCONNECT, MF_BYCOMMAND);

    switch (action) {
    case ID_MENU_NONE:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("None"));
	SetWindowText(hwndActionButton, TEXT("-"));
	break;
    case ID_MENU_CALL:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Call"));
	SetWindowText(hwndActionButton, TEXT("&Call"));
	break;
    case ID_MENU_ANSWER:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Answer"));
	SetWindowText(hwndActionButton, TEXT("&Answer"));
	break;
    case ID_MENU_DISCONNECT:
	InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Hangup"));
	SetWindowText(hwndActionButton, TEXT("&Hangup"));
	break;
    }

    EnableMenuItem(hMenu, action, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED));
    DrawMenuBar(hMainWnd);

    g_current_action = action;
}


/*
 * Handler when invite state has changed.
 */
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
    pjsua_call_info call_info;

    PJ_UNUSED_ARG(e);

    pjsua_call_get_info(call_id, &call_info);

    if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {

	g_current_call = PJSUA_INVALID_ID;
	SetURI(SIP_DST_URI, -1);
	SetAction(ID_MENU_CALL);
	//SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen);
	SetCallStatus(call_info.last_status_text.ptr, call_info.last_status_text.slen);

    } else {
	//if (g_current_call == PJSUA_INVALID_ID)
	//    g_current_call = call_id;

	if (call_info.remote_contact.slen)
	    SetURI(call_info.remote_contact.ptr, call_info.remote_contact.slen, false);
	else
	    SetURI(call_info.remote_info.ptr, call_info.remote_info.slen, false);

	if (call_info.state == PJSIP_INV_STATE_CONFIRMED)
	    SetAction(ID_MENU_DISCONNECT);

	SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen);
    }
}


/*
 * Callback on media state changed event.
 * The action may connect the call to sound device, to file, or
 * to loop the call.
 */
static void on_call_media_state(pjsua_call_id call_id)
{
    pjsua_call_info call_info;

    pjsua_call_get_info(call_id, &call_info);

    if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
	pjsua_conf_connect(call_info.conf_slot, 0);
	pjsua_conf_connect(0, call_info.conf_slot);
    }
}


/**
 * Handler when there is incoming call.
 */
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
			     pjsip_rx_data *rdata)
{
    pjsua_call_info call_info;

    PJ_UNUSED_ARG(acc_id);
    PJ_UNUSED_ARG(rdata);

    if (g_current_call != PJSUA_INVALID_ID) {
	pj_str_t reason;
	reason = pj_str("Another call is in progress");
	pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, &reason, NULL);
	return;
    }

    g_current_call = call_id;

    pjsua_call_get_info(call_id, &call_info);

    SetAction(ID_MENU_ANSWER);
    SetURI(call_info.remote_info.ptr, call_info.remote_info.slen, false);
    pjsua_call_answer(call_id, 200, NULL, NULL);
}


/*
 * Handler registration status has changed.
 */
static void on_reg_state(pjsua_acc_id acc_id)
{
    PJ_UNUSED_ARG(acc_id);

    // Log already written.
}


/*
 * Handler on buddy state changed.
 */
static void on_buddy_state(pjsua_buddy_id buddy_id)
{
}


/**
 * Incoming IM message (i.e. MESSAGE request)!
 */
static void on_pager(pjsua_call_id call_id, const pj_str_t *from, 
		     const pj_str_t *to, const pj_str_t *contact,
		     const pj_str_t *mime_type, const pj_str_t *text)
{
}


/**
 * Received typing indication
 */
static void on_typing(pjsua_call_id call_id, const pj_str_t *from,
		      const pj_str_t *to, const pj_str_t *contact,
		      pj_bool_t is_typing)
{
}


static BOOL OnInitStack(void)
{
    pjsua_config	    cfg;
    pjsua_logging_config    log_cfg;
    pjsua_media_config	    media_cfg;
    pjsua_transport_config  udp_cfg;
    pjsua_transport_config  rtp_cfg;
    pjsua_transport_id	    transport_id;
    pjsua_transport_info    transport_info;
    pj_str_t		    tmp;
    pj_status_t status;

    /* Create pjsua */
    status = pjsua_create();
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Error creating pjsua"), status);
	return FALSE;
    }

    /* Create global pool for application */
    g_pool = pjsua_pool_create("pjsua", 4000, 4000);

    /* Init configs */
    pjsua_config_default(&cfg);
    pjsua_media_config_default(&media_cfg);
    pjsua_transport_config_default(&udp_cfg);
    udp_cfg.port = SIP_PORT;

    pjsua_transport_config_default(&rtp_cfg);
    rtp_cfg.port = 40000;

    pjsua_logging_config_default(&log_cfg);
    log_cfg.level = 5;
    log_cfg.log_filename = pj_str("\\pjsua.txt");
    log_cfg.msg_logging = 1;
    log_cfg.decor = pj_log_get_decor() | PJ_LOG_HAS_CR;

    /* Setup media */
    media_cfg.clock_rate = 8000;
    media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE;
    media_cfg.ec_tail_len = 256;
    media_cfg.quality = 1;
    media_cfg.ptime = 20;
    media_cfg.enable_ice = USE_ICE;

    /* Initialize application callbacks */
    cfg.cb.on_call_state = &on_call_state;
    cfg.cb.on_call_media_state = &on_call_media_state;
    cfg.cb.on_incoming_call = &on_incoming_call;
    cfg.cb.on_reg_state = &on_reg_state;
    cfg.cb.on_buddy_state = &on_buddy_state;
    cfg.cb.on_pager = &on_pager;
    cfg.cb.on_typing = &on_typing;

    if (SIP_PROXY) {
	    cfg.outbound_proxy_cnt = 1;
	    cfg.outbound_proxy[0] = pj_str(SIP_PROXY);
    }
    
    if (NAMESERVER) {
	    cfg.nameserver_count = 1;
	    cfg.nameserver[0] = pj_str(NAMESERVER);
    }
    
    if (NAMESERVER && STUN_DOMAIN) {
	    cfg.stun_domain = pj_str(STUN_DOMAIN);
    } else if (STUN_SERVER) {
	    cfg.stun_host = pj_str(STUN_SERVER);
    }
    
    
    /* Initialize pjsua */
    status = pjsua_init(&cfg, &log_cfg, &media_cfg);
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Initialization error"), status);
	return FALSE;
    }

    /* Set codec priority */
    pjsua_codec_set_priority(pj_cstr(&tmp, "pcmu"), 240);
    pjsua_codec_set_priority(pj_cstr(&tmp, "pcma"), 230);
    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/8000"), 190);
    pjsua_codec_set_priority(pj_cstr(&tmp, "ilbc"), 189);
    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/16000"), 180);
    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/32000"), 0);
    pjsua_codec_set_priority(pj_cstr(&tmp, "gsm"), 100);


    /* Add UDP transport and the corresponding PJSUA account */
    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
				    &udp_cfg, &transport_id);
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Error starting SIP transport"), status);
	return FALSE;
    }

    pjsua_transport_get_info(transport_id, &transport_info);

    g_local_uri.ptr = (char*)pj_pool_alloc(g_pool, 128);
    g_local_uri.slen = pj_ansi_sprintf(g_local_uri.ptr,
				       "<sip:%.*s:%d>",
				       (int)transport_info.local_name.host.slen,
				       transport_info.local_name.host.ptr,
				       transport_info.local_name.port);


    /* Add local account */
    pjsua_acc_add_local(transport_id, PJ_TRUE, &g_current_acc);
    pjsua_acc_set_online_status(g_current_acc, PJ_TRUE);

    /* Add account */
    if (HAS_SIP_ACCOUNT) {
	pjsua_acc_config cfg;

	pjsua_acc_config_default(&cfg);
	cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
	cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
	cfg.cred_count = 1;
	cfg.cred_info[0].realm = pj_str(SIP_REALM);
	cfg.cred_info[0].scheme = pj_str("digest");
	cfg.cred_info[0].username = pj_str(SIP_USER);
	cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
	cfg.cred_info[0].data = pj_str(SIP_PASSWD);

	status = pjsua_acc_add(&cfg, PJ_TRUE, &g_current_acc);
	if (status != PJ_SUCCESS) {
	    pjsua_destroy();
	    return PJ_FALSE;
	}
    }

    /* Add buddy */
    if (SIP_DST_URI) {
    	pjsua_buddy_config bcfg;
    
    	pjsua_buddy_config_default(&bcfg);
    	bcfg.uri = pj_str(SIP_DST_URI);
    	bcfg.subscribe = PJ_FALSE;
    	
    	pjsua_buddy_add(&bcfg, NULL);
    }

    /* Start pjsua */
    status = pjsua_start();
    if (status != PJ_SUCCESS) {
	OnError(TEXT("Error starting pjsua"), status);
	return FALSE;
    }

    return TRUE;
}


//////////////////////////////////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hInstance,
		   HINSTANCE hPrevInstance,
		   LPTSTR    lpCmdLine,
		   int       nCmdShow)
{
    MSG msg;
    HACCEL hAccelTable;
    


    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow)) 
    {
	return FALSE;
    }
    
    hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PJSUA_WINCE);
    
    
    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0)) 
    {
	if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
	{
	    TranslateMessage(&msg);
	    DispatchMessage(&msg);
	}
    }
    
    return msg.wParam;
}

static ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
    WNDCLASS wc;

    wc.style		= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc	= (WNDPROC) WndProc;
    wc.cbClsExtra	= 0;
    wc.cbWndExtra	= 0;
    wc.hInstance	= hInstance;
    wc.hIcon		= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PJSUA_WINCE));
    wc.hCursor		= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName	= 0;
    wc.lpszClassName	= szWindowClass;

    return RegisterClass(&wc);
}


/* Callback upon NAT detection completion */
static void nat_detect_cb(const pj_stun_nat_detect_result *res)
{
    if (res->status != PJ_SUCCESS) {
	char msg[250];
	pj_ansi_snprintf(msg, sizeof(msg), "NAT detection failed: %s",
			 res->status_text);
	SetCallStatus(msg, pj_ansi_strlen(msg));
    } else {
	char msg[250];
	pj_ansi_snprintf(msg, sizeof(msg), "NAT type is %s",
			 res->nat_type_name);
	SetCallStatus(msg, pj_ansi_strlen(msg));
    }
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND	hWnd;
    TCHAR	szTitle[MAX_LOADSTRING];
    TCHAR	szWindowClass[MAX_LOADSTRING];

    hInst = hInstance;

    /* Init stack */
    if (OnInitStack() == FALSE)
	return FALSE;

    LoadString(hInstance, IDC_PJSUA_WINCE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance, szWindowClass);

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 200, 
	    NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {	
	    return FALSE;
    }

    hMainWnd = hWnd;
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    if (hwndCB)
	CommandBar_Show(hwndCB, TRUE);

    SetTimer(hMainWnd, ID_POLL_TIMER, 50, NULL);

    pjsua_detect_nat_type();
    return TRUE;
}


static void OnCreate(HWND hWnd)
{
    enum 
    {
	X = 10,
	Y = 40,
	W = 220,
	H = 30,
    };

    DWORD dwStyle;

    hMainWnd = hWnd;

    hwndCB = CommandBar_Create(hInst, hWnd, 1);			
    CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);   
    CommandBar_AddAdornments(hwndCB, 0, 0);

    // Create global status text
    dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED | ES_LEFT;  
    hwndGlobalStatus = CreateWindow(
                TEXT("EDIT"),   // Class name
                NULL,           // Window text
                dwStyle,        // Window style
                X,		// x-coordinate of the upper-left corner
                Y+0,            // y-coordinate of the upper-left corner
                W,		// Width of the window for the edit
                                // control
                H-5,		// Height of the window for the edit
                                // control
                hWnd,           // Window handle to the parent window
                (HMENU) ID_GLOBAL_STATUS, // Control identifier
                hInst,           // Instance handle
                NULL);          // Specify NULL for this parameter when 
                                // you create a control
    SetLocalURI(g_local_uri.ptr, g_local_uri.slen, false);


    // Create URI edit
    dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER;  
    hwndURI = CreateWindow (
                TEXT("EDIT"),   // Class name
                NULL,		// Window text
                dwStyle,        // Window style
                X,  // x-coordinate of the upper-left corner
                Y+H,  // y-coordinate of the upper-left corner
                W,  // Width of the window for the edit
                                // control
                H-5,  // Height of the window for the edit
                                // control
                hWnd,           // Window handle to the parent window
                (HMENU) ID_URI, // Control identifier
                hInst,           // Instance handle
                NULL);          // Specify NULL for this parameter when 
                                // you create a control

    // Create action Button
    hwndActionButton = CreateWindow( L"button", L"Action", 
                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                         X, Y+2*H, 
			 60, H-5, hWnd, 
                         (HMENU) ID_BTN_ACTION,
                         hInst, NULL );

    // Create exit button
    hwndExitButton = CreateWindow( L"button", L"E&xit", 
                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                         X+70, Y+2*H, 
			 60, H-5, hWnd, 
                         (HMENU) ID_EXIT,
                         hInst, NULL );


    // Create call status edit
    dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED;  
    hwndCallStatus = CreateWindow (
                TEXT("EDIT"),   // Class name
                NULL,		// Window text
                dwStyle,        // Window style
                X,  // x-coordinate of the upper-left corner
                Y+3*H,  // y-coordinate of the upper-left corner
                W,  // Width of the window for the edit
                                // control
                H-5,  // Height of the window for the edit
                                // control
                hWnd,           // Window handle to the parent window
                (HMENU) ID_CALL_STATUS, // Control identifier
                hInst,           // Instance handle
                NULL);          // Specify NULL for this parameter when 
                                // you create a control
    SetCallStatus("Ready", 5);
    SetAction(ID_MENU_CALL);
    SetURI(SIP_DST_URI, -1);
    SetFocus(hWnd);

}


static void OnDestroy(void)
{
    pjsua_destroy();
}

static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    
    switch (message) {
    case WM_KEYUP:
	if (wParam==114) {
	    wParam = ID_MENU_CALL;
	} else if (wParam==115) {
	    if (g_current_call == PJSUA_INVALID_ID)
		wParam = ID_EXIT;
	    else
		wParam = ID_MENU_DISCONNECT;
	} else
	    break;

    case WM_COMMAND:
	wmId    = LOWORD(wParam); 
	wmEvent = HIWORD(wParam); 
	if (wmId == ID_BTN_ACTION)
	    wmId = g_current_action;
	switch (wmId)
	{
	case ID_MENU_CALL:
	    if (g_current_call != PJSUA_INVALID_ID) {
		MessageBox(NULL, TEXT("Can not make call"), 
			   TEXT("You already have one call active"), MB_OK);
	    }
	    pj_str_t dst_uri;
	    wchar_t text[256];
	    char tmp[256];
	    pj_status_t status;

	    GetWindowText(hwndURI, text, PJ_ARRAY_SIZE(text));
	    pj_unicode_to_ansi(text, pj_unicode_strlen(text),
			       tmp, sizeof(tmp));
	    dst_uri.ptr = tmp;
	    dst_uri.slen = pj_ansi_strlen(tmp);
	    status = pjsua_call_make_call(g_current_acc,
						      &dst_uri, 0, NULL,
						      NULL, &g_current_call);
	    if (status != PJ_SUCCESS)
		OnError(TEXT("Unable to make call"), status);
	    break;
	case ID_MENU_ANSWER:
	    if (g_current_call == PJSUA_INVALID_ID)
		MessageBox(NULL, TEXT("Can not answer"), 
			   TEXT("There is no call!"), MB_OK);
	    else
		pjsua_call_answer(g_current_call, 200, NULL, NULL);
	    break;
	case ID_MENU_DISCONNECT:
	    if (g_current_call == PJSUA_INVALID_ID)
		MessageBox(NULL, TEXT("Can not disconnect"), 
			   TEXT("There is no call!"), MB_OK);
	    else
		pjsua_call_hangup(g_current_call, PJSIP_SC_DECLINE, NULL, NULL);
	    break;
	case ID_EXIT:
	    DestroyWindow(hWnd);
	    break;
	default:
	    return DefWindowProc(hWnd, message, wParam, lParam);
	}
	break;

    case WM_CREATE:
	OnCreate(hWnd);
	break;

    case WM_DESTROY:
	OnDestroy();
	CommandBar_Destroy(hwndCB);
	PostQuitMessage(0);
	break;

    case WM_TIMER:
	pjsua_handle_events(1);
	break;

    default:
	return DefWindowProc(hWnd, message, wParam, lParam);
    }
   return 0;
}

