📄 glwclient_w32.c
字号:
/* * gui - [gega user interface] the flexible solution for user interface problems * Copyright (C) 2002 Gergely Gati * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Gergely Gati * email: g.gati@freemail.hu * AIM screenname: GatiGergely * ICQ number: 93131690 * */#include <windows.h>#include <stdlib.h>#include <string.h>#include <time.h>#undef GLW_SERVER#include <NetCommon.h>#include <Glw.h>#include <Memory.h>#include <debug.h>#include <Net.h>#include <Client.h>//#include <Prefs.h>#define SOCK_CLOSE_BUFSIZE 256static char client_loopback[]="127.0.0.1";static char *client_address=client_loopback;static HWND global_window;static struct glw_Connection *global_conn;static int quit=0;static int async=0;struct glw_Connection{ struct glw_ConnUser cuser; SOCKET sd; struct glw_SockMsg sockmsg; u32 completed; u8 *write_buffer;};struct glw_Timer{ u32 userdata;// net_Window_t *nwin; u32 id;};static struct glw_Event curr_event;u32 glw_htonl(u32 value){ return(htonl(value));}u32 glw_ntohl(u32 value){ return(ntohl(value));}int glw_Recv(u32 connection, u8 *buff, int bufflen){ struct glw_Connection *conn=(struct glw_Connection *)connection; int ret=0; debug_Begin(); if(conn!=NULL&&buff!=NULL&&bufflen>0) { ret=recv(conn->sd,buff,bufflen,0); } debug_End(); return(ret);}int glw_Send(u32 connection, u8 *buff, int bufflen){ struct glw_Connection *conn=(struct glw_Connection *)connection; int ret=0; debug_Begin(); if(conn!=NULL&&buff!=NULL&&bufflen>0) { ret=send(conn->sd,buff,bufflen,0); } debug_End(); return(ret);}int glw_SendMsg(u32 connection, u8 type, u32 id, u8 *buff, int bufflen){ struct glw_Connection *conn=(struct glw_Connection *)connection; u8 header[GLW_HEADER_LENGTH]; int mlen; debug_Begin(); mlen=bufflen+GLW_HEADER_LENGTH;//printf("OUTGOING Message %d bytes + %d bytes header (total: %d)\n",bufflen,GLW_HEADER_LENGTH,mlen);//if(bufflen>3) printf("msg: %02x %02x %02x %02x (%c%c%c%c)\n",buff[0],buff[1],buff[2],buff[3],buff[0],buff[1],buff[2],buff[3]); header[0]='?'; header[1]=type; *((u32 *)&header[2])=htonl(mlen); *((u32 *)&header[6])=htonl(id); if(mlen<NET_WRITE_BUFFER_SIZE) { memcpy(conn->write_buffer,header,GLW_HEADER_LENGTH); if(bufflen>0) memcpy(conn->write_buffer+GLW_HEADER_LENGTH,buff,bufflen); send(conn->sd,conn->write_buffer,mlen,0); } else { send(conn->sd,header,GLW_HEADER_LENGTH,0); if(bufflen>0&&buff!=NULL) send(conn->sd,buff,bufflen,0); } debug_End(); return(0);}static void glw_Client(char *address, int port){ struct in_addr Address; SOCKET sd; u_long RemoteAddress; struct hostent *pHE; struct sockaddr_in sinRemote; WSADATA wsaData; struct glw_Connection *conn; int NewBytes; char ReadBuffer[SOCK_CLOSE_BUFSIZE]; debug_Begin(); if(WSAStartup(MAKEWORD(1,1),&wsaData)==0) { printf("Establishing the client...\n"); RemoteAddress=inet_addr(address); if(RemoteAddress==INADDR_NONE) { pHE=gethostbyname(address); if(pHE!=0) { RemoteAddress=*((u_long*)pHE->h_addr_list[0]); } } if(RemoteAddress!=INADDR_NONE) { memcpy(&Address,&RemoteAddress,sizeof(u_long)); sd=socket(AF_INET, SOCK_STREAM, 0); if(sd!=INVALID_SOCKET) { sinRemote.sin_family=AF_INET; sinRemote.sin_addr.s_addr=RemoteAddress; sinRemote.sin_port=htons(port); if(connect(sd,(struct sockaddr *)&sinRemote,sizeof(struct sockaddr_in))==SOCKET_ERROR) { sd=INVALID_SOCKET; } } if(INVALID_SOCKET!=sd) { if(NULL!=(conn=mem_calloc(1,sizeof(struct glw_Connection)))) { if(NULL!=(conn->write_buffer=mem_malloc(NET_WRITE_BUFFER_SIZE))) { conn->sd=sd; printf("connected to server\n"); client_Init((u32)conn); mem_free(conn->write_buffer); } mem_free(conn); } if(shutdown(sd,SD_SEND)!=SOCKET_ERROR) { while(1) { NewBytes=recv(sd,ReadBuffer,SOCK_CLOSE_BUFSIZE,0); if(NewBytes==0||NewBytes==SOCKET_ERROR) break; } closesocket(sd); } } } WSACleanup(); } debug_End();}static int glw_ReadMessage(struct glw_Connection *conn){ char header[GLW_HEADER_LENGTH]; int rcv=0,r=0,ret=0; SYSTEMTIME stime; if(conn->completed==0) { // new message while(rcv<GLW_HEADER_LENGTH) { if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0) { if(WSAGetLastError()==WSAEWOULDBLOCK) { fd_set fdread; FD_ZERO(&fdread); FD_SET(conn->sd,&fdread); if((r=select(0,&fdread,NULL,NULL,NULL))==SOCKET_ERROR) break; } else break; if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0) break; } rcv+=r; } if(r>=0&&header[0]=='?') { conn->sockmsg.type=(int)header[1]; conn->sockmsg.length=ntohl(*((u32 *)&header[2])); conn->sockmsg.id=ntohl(*((u32 *)&header[6])); conn->sockmsg.body=mem_malloc(conn->sockmsg.length-GLW_HEADER_LENGTH); conn->completed=GLW_HEADER_LENGTH;// printf("%s() legal message header: type=0x%02x id=%ld len=%ld\n",__FUNCTION__,(u8)conn->sockmsg.type,conn->sockmsg.id,conn->sockmsg.length); if(conn->sockmsg.body==NULL) { // HIBA!! conn->completed=0; } } else { // HIBA!! ret=-1; if(r>0) { int i,j,c; printf("***BAD MESSAGE:\n "); for(j=i=0;i<r;i++) { c=*(header+rcv-r+i); printf("%02x '%c' ",(unsigned short)c,(c>32||c<127?c:'.')); if((++j%8)==0) printf("\n "); } printf("\n"); } else { printf("***BAD MESSAGE ret=%d errcode=%d\n",r,WSAGetLastError()); } } } else { // partial message r=recv( conn->sd,conn->sockmsg.body+conn->completed-GLW_HEADER_LENGTH, conn->sockmsg.length-conn->completed,0); if(r>0) { conn->completed+=r; if(conn->completed>=conn->sockmsg.length) { conn->completed=0; curr_event.event=GLWEV_SOCKET; curr_event.data=(u32)&conn->sockmsg; curr_event.second=(u32)time(NULL); GetSystemTime(&stime); curr_event.millis=stime.wMilliseconds; } } } return(ret);}int glw_MainLoopCli(u32 connection, u32 userdata){//static int cnt=0; struct glw_Connection *conn=(struct glw_Connection *)connection; MSG Message; debug_Begin();//printf("\nMAINLOOP START %d\n",cnt++); global_conn=conn; do { if(async==0) { WSAAsyncSelect(conn->sd,global_window,WM_APP,FD_READ); async=1; } quit=0; curr_event.event=0L; curr_event.window=0L; curr_event.userdata=userdata; curr_event.mousex=curr_event.mousey=0; GetMessage(&Message,NULL,0,0); TranslateMessage(&Message); // keycode conversion DispatchMessage(&Message); // call StdWindowProc() (retval==StdWindowProc's retval)// if(glw_ReadMessage(conn)<0) break;//printf(" 1: quit=%d\n",quit); if(curr_event.event!=0L&&0!=client_CliProcessMessage(connection,curr_event.userdata,(struct glw_SockMsg *)curr_event.data)) break;//printf(" 2: quit=%d\n",quit); } while(quit==0); WSAAsyncSelect(conn->sd,global_window,0,0); async=0;//printf("MAINLOOP STOP %d\n",--cnt); debug_End(); return(0);}/*int main(int argc, char **argv){ if(argc>1) client_address=argv[1]; prefs_Init(); glw_Client(client_address, net_GetPort()); prefs_CleanUp(); mem_trace_report(); return(0);}*/LRESULT CALLBACK glw_StdWindowProc(HWND Window, UINT MessageType, WPARAM FirstParameter, LPARAM SecondParameter){ LRESULT ret=1L; debug_Begin(); switch(MessageType) { case WM_TIMER: { struct glw_Timer *timer=(struct glw_Timer *)FirstParameter;//printf("TIMER!!!\n"); // userdata: FirstParameter // event: GLWEV_TIMER if(timer!=NULL) {//printf(" CODE (%ld)\n",timer->userdata); client_TimerHandler((u32)timer,timer->userdata);// timer->nwin->event_handler(timer->nwin->app,timer->nwin->window,0L,GLWEV_TIMER,timer->userdata); KillTimer(global_window,timer->id); ret=0; } break; } case WM_APP: {// if(0>glw_ReadMessage(global_conn)) quit=1; if(0>glw_ReadMessage(global_conn)) printf("***BAD MESSAGE!!\n"); ret=0; break; } } debug_End(); return(ret);}int WINAPI WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, int CommandShow){ WNDCLASSEX WindowClass; debug_Begin(); if(strlen(CommandLine)>=7) client_address=CommandLine; WindowClass.cbSize = sizeof(WNDCLASSEX); WindowClass.style = 0; WindowClass.lpfnWndProc = glw_StdWindowProc; WindowClass.cbClsExtra = 0; WindowClass.cbWndExtra = 0; WindowClass.hInstance = Instance; WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); WindowClass.hbrBackground = GetStockObject(WHITE_BRUSH); WindowClass.lpszMenuName = NULL; WindowClass.lpszClassName = "glw_StdClientWC"; WindowClass.hIconSm = NULL; if(RegisterClassEx(&WindowClass)!=0) { if((global_window=CreateWindowEx( WS_EX_OVERLAPPEDWINDOW, "glw_StdClientWC", NULL, WS_OVERLAPPED, 1, 1, 3, 3, NULL, NULL, Instance, NULL))!=NULL) { ShowWindow(global_window,SW_HIDE);// prefs_Init(); glw_Client(client_address,net_GetPort());// prefs_CleanUp(); DestroyWindow(global_window); } } mem_trace_report(); debug_End(); return(0L);}u32 glw_TimerStart(u32 window, u32 millisec, u32 userdata){ struct glw_Timer *timer; u32 id; debug_Begin(); if(NULL!=(timer=mem_malloc(sizeof(struct glw_Timer)))) { timer->userdata=userdata;// id=SetTimer(global_window,(u32)timer,(UINT)millisec,NULL);//printf("set timer %ld ms\n",millisec); id=SetTimer(global_window,(u32)timer,(UINT)millisec,(TIMERPROC)NULL); timer->id=id; } debug_End(); return((u32)timer);}void glw_TimerCancel(u32 window, u32 id){ struct glw_Timer *timer=(struct glw_Timer *)id; debug_Begin(); if(timer!=NULL) { KillTimer(global_window,timer->id); mem_free(timer); } debug_End();}void glw_CloseApp(u32 connection){ quit=1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -