📄 glw_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 * *//* glw.c */#include <windows.h>//#include <shlobj.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <Bases.h>#include <NetCommon.h>#include <Memory.h>#include <debug.h>#include <Net.h>#include <Image.h>#include <Gadget.h>#include <Common.h>struct glw_Window{ HWND window; u32 fgrgb; u32 bgrgb; COLORREF fgcol; // __BBGGRR COLORREF bgcol; HBRUSH fgbrush; HBRUSH bgbrush; HPEN pen; LOGBRUSH logbrush; HDC hdcMem; HBITMAP hbmMem; HBITMAP hbmOld; RECT wrect; u32 flags; u32 userdata; int minwidth; int maxwidth; int minheight; int maxheight; int done; struct glw_Connection *conn; int state; int paint; int user_state;};struct glw_Connection{ struct glw_ConnUser cuser; SOCKET sd;// DWORD thread_id; int window_count; struct glw_Window *win; struct glw_SockMsg sockmsg; u32 completed; u8 *write_buffer; struct glw_Event curr_event; int level; int mx,my; List_t *windowlist;};struct glw_FontFace{ char *face; char *win_name;};struct glw_Font{ Node_t *node; struct glw_FontFace *face; int size; u32 style; HFONT handle; int counter;};struct glw_Dir{ HANDLE hdir; char *filename;};#define NWHT_NOWHERE 0x0000#define NWHT_LEFT 0x0001#define NWHT_RIGHT 0x0002#define NWHT_TOP 0x0003#define NWHT_TOPLEFT 0x0004#define NWHT_TOPRIGHT 0x0005#define NWHT_BOTTOM 0x0006#define NWHT_BOTTOMLEFT 0x0007#define NWHT_BOTTOMRIGHT 0x0008#ifndef ANTIALIASED_QUALITY#define ANTIALIASED_QUALITY 4#endif#define GLW_FONTNAME_SIZE 64struct glw_InternalBMI{ BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[3];};//Declare call_vector[]static u32 (*call_vector[GLW_FUNC_DONE-GLW_FUNCBASE+1])(tag *);// double buffer variablesstatic int buffsizeX,buffsizeY;static List_t *windowlist; //SEMAPHORE PROTECTED!static WNDCLASSEX WindowClass;static int sCommandShow;static List_t *fontfacelist; //readonly list no need semaphorestatic List_t *fontlist; //SEMAPHORE PROTECTED!static int wv; // windows version: 0=>3.1 1=>95 2=>98 3=>NT4 4=>2k 5=>xpstatic HINSTANCE sInstance;// app-dependent stuffstatic HDC workDC=NULL; // used by glw_GetTextLength() only a) SEMAPHORE PROTECTION, b) window or app specific!u32 glw_GetConnection(u32 window){ struct glw_Window *win=(struct glw_Window *)window; return((u32)win->conn);}static void glw_UnloadFontFaces(List_t *faces){ Node_t *node; struct glw_FontFace *face; debug_Begin(); while(NULL!=(node=list_GetNodeHead(faces))) { list_RemoveNode(faces,node); if(NULL!=(face=(struct glw_FontFace *)list_GetNodeData(node))) { if(NULL!=face->face) mem_free(face->face); if(NULL!=face->win_name) mem_free(face->win_name); mem_free(face); } list_SetNodeData(node,NULL); list_DeleteNode(node); } list_DeleteList(faces); debug_End();}static int glw_LoadFontFaces(List_t *faces){ int ret=-1; FILE *f; char str[GLW_FONTNAME_SIZE]; struct glw_FontFace *face; Node_t *node; char *eq; debug_Begin(); if(faces!=NULL) { if(NULL!=(f=fopen("files/Fonts.list","r"))) { while(NULL!=(fgets(str,GLW_FONTNAME_SIZE,f))) { str[strlen(str)-1]='\0'; if(NULL!=(eq=strchr(str,'='))) { *eq++='\0'; ret=-1; if(NULL!=(node=list_CreateNode())) { if(NULL!=(face=mem_malloc(sizeof(struct glw_FontFace)))) { if(NULL!=(face->face=mem_malloc(strlen(str)+1))) { strcpy(face->face,str); if(NULL!=(face->win_name=mem_malloc(strlen(eq)+1))) { strcpy(face->win_name,eq); list_SetNodeData(node,face); list_InsertNodeTail(faces,node); ret=0; } } } } } } fclose(f); } } debug_End(); return(ret);}static struct glw_FontFace *glw_GetFaceWinName(List_t *fflist, char *name){ Node_t *node; struct glw_FontFace *face=NULL; debug_Begin(); for(node=list_GetNodeHead(fflist);node!=NULL;node=list_GetNodeNext(fflist,node)) { if(NULL!=(face=list_GetNodeData(node))) { if(strcmp(face->face,name)==0) break; } } debug_End(); return(face);}static void glw_CreateBuffer(struct glw_Window *win, HDC referenceDC, int sizeX, int sizeY){ debug_Begin(); if((win->flags&GLWF_SMART_REFRESH)!=0) { win->hdcMem=CreateCompatibleDC(referenceDC); win->hbmMem=CreateCompatibleBitmap(referenceDC,sizeX,sizeY); win->hbmOld=SelectObject(win->hdcMem, win->hbmMem); } else win->hdcMem=GetDC(win->window); win->fgcol=0x00000000; // __BBGGRR win->bgcol=0x00ffffff; win->fgbrush=CreateSolidBrush(win->fgcol); win->bgbrush=CreateSolidBrush(win->bgcol); win->logbrush.lbStyle=BS_SOLID; win->logbrush.lbColor=win->fgcol; win->pen=ExtCreatePen(PS_COSMETIC|PS_SOLID,1,&win->logbrush,0,NULL); debug_End();}int glw_ClearWindow(u32 window){ struct glw_Window *win; RECT rc; debug_Begin(); win=(struct glw_Window *)window; if(win->bgrgb!=GLW_TRANSPARENT) { rc.left=rc.top=0; rc.bottom=buffsizeY; rc.right=buffsizeX; FillRect(win->hdcMem,&rc,win->bgbrush); } debug_End(); return(0);}static void glw_DeleteBuffer(struct glw_Window *win){ debug_Begin(); DeleteObject(win->fgbrush); DeleteObject(win->bgbrush); DeleteObject(win->pen); if((win->flags&GLWF_SMART_REFRESH)!=0) { SelectObject(win->hdcMem, win->hbmOld); DeleteObject(win->hbmMem); DeleteDC(win->hdcMem); } debug_End();}static Node_t *glw_GetNode(HWND win){ Node_t *node; Node_t *ret=NULL; struct glw_Window *w; debug_Begin(); for(node=list_GetNodeHead(windowlist);node!=NULL;node=list_GetNodeNext(windowlist,node)) { w=(struct glw_Window *)list_GetNodeData(node); if(w->window==win) { ret=node; break; } } debug_End(); return(ret);}static Node_t *glw_GetNode2(struct glw_Connection *conn, HWND win){ Node_t *node; Node_t *ret=NULL; struct glw_Window *w; debug_Begin(); for(node=list_GetNodeHead(conn->windowlist);node!=NULL;node=list_GetNodeNext(conn->windowlist,node)) { w=(struct glw_Window *)list_GetNodeData(node); if(w->window==win) { ret=node; break; } } debug_End(); return(ret);}static struct glw_Window *glw_GetGlwWindow(HWND w){ struct glw_Window *win=NULL; Node_t *node; debug_Begin(); if((node=glw_GetNode(w))!=NULL) { win=(struct glw_Window *)list_GetNodeData(node); } debug_End(); return(win);}static int glw_FillEvent(struct glw_Event *ev, struct glw_Window *win){ int ret=-1; SYSTEMTIME stime; debug_Begin(); if(ev!=NULL) { GetSystemTime(&stime); ev->window=(u32)win; ev->second=(u32)time(NULL); ev->millis=stime.wMilliseconds; ret=0; } debug_End(); return(ret);}static void glw_CopyBck(struct glw_Window *win, RECT *rct){ RECT rc; RECT *myrect=&rc; HDC hDC; Rect_t grct;/// HBITMAP hbmOld; debug_Begin(); if(rct==NULL) { rc.left=rc.top=0; rc.right=win->wrect.right-win->wrect.left; rc.bottom=win->wrect.bottom-win->wrect.top; } else myrect=rct; if((win->flags&GLWF_SMART_REFRESH)==0) { glw_FillEvent(&win->conn->curr_event,win); grct.left=myrect->left; grct.top=myrect->top; grct.width=myrect->right-myrect->left; grct.height=myrect->bottom-myrect->top; win->conn->curr_event.event=GLWEV_DAMAGE; win->conn->curr_event.data=(u32)&grct; win->done|=gui_Event((u32)win->conn,&win->conn->curr_event); } else {/// hbmOld=SelectObject(win->hdcMem,win->hbmMem); hDC=GetDC(win->window); BitBlt(hDC,myrect->left,myrect->top,myrect->right-myrect->left,myrect->bottom-myrect->top,win->hdcMem,myrect->left,myrect->top,SRCCOPY); ReleaseDC(win->window,hDC);/// SelectObject(win->hdcMem,hbmOld); } debug_End();}static void glw_CopyBckIndirect(HWND hwnd,RECT *rct){ struct glw_Window *win; Node_t *node; debug_Begin(); if((node=glw_GetNode(hwnd))!=NULL) { if(NULL!=(win=(struct glw_Window *)list_GetNodeData(node))) glw_CopyBck(win,rct); } 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 { debug_Error("socket error: %d",WSAGetLastError()); conn->cuser.quit=1; break; } if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0) { debug_Error("socket error (2): %d",WSAGetLastError()); conn->cuser.quit=1; break; } } rcv+=r; } if(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=-1; } } else { // HIBA!! debug_Error("unknown message (%p) -> header=%02x type=%d",conn,(unsigned char)header[0],header[1]);/// conn->completed=-1; } } 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; conn->curr_event.event=GLWEV_SOCKET; conn->curr_event.data=(u32)&conn->sockmsg; conn->curr_event.second=(u32)time(NULL); GetSystemTime(&stime); conn->curr_event.millis=stime.wMilliseconds; } } } return(ret);}LRESULT CALLBACK glw_StdWindowProc(HWND Window, UINT MessageType, WPARAM FirstParameter, LPARAM SecondParameter){ PAINTSTRUCT ps; POINTS pnts; LRESULT ret=1L; struct glw_Window *win; struct glw_Connection *conn=NULL; debug_Begin(); win=glw_GetGlwWindow(Window); if(win!=NULL) { conn=win->conn; if(win->user_state==GLWWS_OPENING) win=NULL; } if(conn!=NULL) { glw_FillEvent(&conn->curr_event,win); conn->curr_event.mousex=conn->mx; conn->curr_event.mousey=conn->my; } switch(MessageType) { case WM_ENTERSIZEMOVE: { if(win!=NULL) { win->state=1; } ret=0; break; } case WM_EXITSIZEMOVE: { if(win!=NULL) { if(win->state==2) { // last WM_SIZING message win->conn->curr_event.event=GLWEV_WINDOW; win->conn->curr_event.data=GLWEVD_SIZEEND; win->done|=gui_Event((u32)win->conn,&win->conn->curr_event); } else if(win->state==3) { // last WM_MOVING message win->conn->curr_event.event=GLWEV_WINDOW; win->conn->curr_event.data=GLWEVD_MOVEEND; win->done|=gui_Event((u32)win->conn,&win->conn->curr_event); } win->state=0; } ret=0; break; } case WM_QUIT: { if(conn!=NULL) { conn->curr_event.event=GLWEV_SYSTEM; conn->curr_event.data=GLWEVD_QUIT; } ret=0; break; } case WM_CLOSE: { DestroyWindow(Window); ret=0; break; } case WM_DESTROY: {// PostQuitMessage(0); ret=0; break; } case WM_ACTIVATE: { if(win!=NULL) { win->conn->curr_event.event=GLWEV_ACTIVATION; if(FirstParameter==WA_INACTIVE) { win->conn->curr_event.data=GLWEVD_INACTIVATE; } else { win->conn->curr_event.data=GLWEVD_ACTIVATE; } win->done|=gui_Event((u32)win->conn,&win->conn->curr_event); } ret=0; break; } case WM_MOUSEMOVE: { pnts=MAKEPOINTS(SecondParameter); if(conn!=NULL) { conn->mx=conn->curr_event.mousex=pnts.x; conn->my=conn->curr_event.mousey=pnts.y; conn->curr_event.event=GLWEV_MOUSEMOVE; conn->curr_event.data=GLWEVD_ABSOLUTE; } DefWindowProc(Window, MessageType, FirstParameter, SecondParameter); ret=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -