全世界最小的看圖程式!!(全新版)執行檔僅3.5k |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
http://tim.jerry.com.tw/?TIM=FORUM&FORUM=59&Page_Method=last_postdate&Page_Sort=desc&offset=0&nextpage=&limit=20&ShowDocument=3040#TIM3040 執行檔僅3.5k!!(3,584 bytes) 全世界最小的看圖程式!!(全新版)
*帖子主題:全世界最小的看圖程式!!(全新版)
相關附件: 共 1639 Bytes
執行檔僅3.5k!!(3,584 bytes)
所需的DLL在Win98之後都內建於系統 支援BMP、JPG、GIF、ICO、WMF等格式
操作簡單,介面也簡單(其實完全沒有介面可言)
使用方法:在圖片上點一下,選下一張圖 雖然沒有仔細求證過,不過應該不會有更小程式的了吧!?
當然,是用C--寫的 說實話,還真寫的我滿頭大汗
現在源碼還很亂,改天再來討論源碼吧!
(如果有人有興趣的話......)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 參考資料 http://www.goosee.com/x86/loadgraphics.htm
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Loading GIF, JPG, BMP, WMF files and viewing them
When I was developing the early beta versions of my new Windows application, EVE (see http://goosee.com), a vector graphics drawing program, it needed to be able to load and insert bitmap graphics images. That is, I wanted to load a graphic file and display it in my application's window. Now, there are libraries available to do this, some of them free. They don't have source code, except for one, called GIFLIB, with MASM source code -- see a link to it from Hutch's MASM site. GIFLIB only loads GIF files.
I used it for the first release of my EVE product, however it is bit buggy and crashes on some GIFs -- the LZW decompressor is the part that crashes. After much hunting around, I found a technical article on Microsoft's web site, describing a program called LOADPIC -- you should be able to locate it from "LOADPIC" as a keyword. This is a C++ program that uses the OleLoadPicture() function. This function is very high-level and will convert GIF, JPG, BMP and WMF files into a format that can be displayed, including the decompressing. This function is not described in Microsoft's SDKs prior to 1998, though the docs state that it works on Win95 -- I haven't tested my program on a wide range of Win95 systems -- the function is in OLEPRO32.DLL and it may not be in older Win95 systems, though I suspect that most will have it, as it is likely that a later application will have loaded it when it got installed. The problem is, I knew nothing about OLE (Object Linking and Embedding) and COM (Common Object Model). For MASM programmers, there's a whole lot of stuff on this topic at Hutch's asm site (or was that Iczelion's site? -- whatever), submitted by Ernie Murphy. Also, this COM stuff is at Ernie's own site: http://here.is/COMinASM. Ok, to tackle this, I took the LOADPIC.CCP application and compiled it using the free Borland C++ compiler -- it gave lots of compile errors, because the code was designed for Microsoft's Visual C++. But, I had set a switch on the compiler to generate an asm file, and at least the compiler got as far as that.
Armed with the asm file, I was able to figure out the code required for my program, however, the key function, OleLoadPicture(), returned an error code. So, I emailed my code to Ernie for his perusal. This greatly intrigued Ernie, as he had no idea that there was such a function to load graphics images (as is the case for just about every other Win32 programmer). Ernie has converted LOADPIC.CCP to LOADPIC.ASM and it is now available at his site. Ernie's approach is very professional, and you have to include lots of macros, include files and link in various library files. I successfully assembled his example program, but I decided to have another look at my original "grassroots" solution. I discovered the bug that was preventing OleLoadPicture() to work, so I have placed my code below. The only extra libraries that you have to link to are OLEPRO32.LIB and OLE32.LIB -- you can find these from various places. You'll need these two prototypes: CreateStreamOnHGlobal PROTO WINAPI, :DWORD, :DWORD, :DWORD
OleLoadPicture PROTO WINAPI, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD I'm talking MASM code here, but you should be able to translate to C or whatever. I'll leave it up to you to write the code to open a file and load it into a memory block. Note that Ernie's example has the code for that. Let's say we have loaded the file and have variable "pmem" pointing to the memory block... Here is my grassroots code for converting the file into a form that can be displayed: .DATA
IID_IPicture DWORD 07bf80980h ;unsigned long.
WORD 0bf32h ;unsigned short.
WORD 0101ah ;unsigned short
BYTE 08bh,0bbh,0,0aah,0,030h,0ch,0abh ;unsigned char Data4[8];
;0x7bf80980,0xbf32,0x101a,0x8b,0xbb,0,0xaa,0,0x30,0xc,0xab gpPicture DWORD 0
E_POINTER EQU 080000005h
E_NOINTERFACE EQU 080000004h
E_OUTOFMEMORY EQU 080000002h .CODE
creategifhdc PROC STDCALL USES ebx ecx edx esi edi, pobj:DWORD,pmem:DWORD,p1stdataelement:DWORD
LOCAL hglobal:DWORD,pstm:DWORD,hr:DWORD
LOCAL widthpixels:DWORD,heightpixels:DWORD
LOCAL hmwidth:DWORD,hmheight:DWORD
;ret eax=0 ok, else error#.
;we enter func with pmem->bitmap-file-in-memory.
mov gpPicture,0 For the OLE/COM functions to use it, the memory block has to be converted into something called a "stream" -- don't ask me what the difference is ... ;now need to convert the mem-block into a "stream"...
invoke GlobalHandle,pmem
mov hglobal,eax
invoke CreateStreamOnHGlobal,hglobal,TRUE,ADDR pstm
;...returns pstm =ptr to stream (i.e. copy of the mem block).
;returns eax=0 if ok
.IF eax != 0
mov eax,220
jmp er0
.ENDIF When I created the memory block, I saved its size, which I'm retrieving here, and calling the magical function OleLoadPicture(). IID_IPicture is a structure that defines what type of information is to be loaded, in this case a graphic image. This function will place a pointer into variable gpPicture, that points to an "interface" -- this is basically a structure, with addresses of "methods" (functions) that can manipulate the data... mov eax,mygifinfo.dwGIFDataSize ;size of mem block.
invoke OleLoadPicture,pstm,eax,0,ADDR IID_IPicture,ADDR gpPicture
;..."IID_IPicture" is the type of interface pointer to return.
;...The requested interface pointer is returned in "gpPicture".
;returns eax=0 if ok
.IF eax != 0 ;S_OK=0
.IF eax==E_POINTER
mov eax,222
.ELSEIF eax==E_NOINTERFACE
mov eax,223
.ELSEIF eax==E_OUTOFMEMORY
mov eax,224
.ELSE
.IF SDWORD PTR eax<0
mov eax,221 ;E_UNEXPECTED
.ELSE
jmp ok9
.ENDIF
.ENDIF
jmp er0
.ENDIF
ok9: I don't need the "stream" anymore. Also, it wasn't in the original LOADPIC code, but I presumed that I also needed to free the original memory block (does releasing the stream also delete the original memory block? -- I have no idea). Release() is a method, and has to be accessed in this manner (see Ernie's code for a more formal way of doing this)... mov eax,pstm ;pstm->Release();
push eax ;/
mov edx,dword ptr [eax] ;/
call dword ptr [edx 8] ;/
;umm, presume can release original mem block?...
invoke GlobalFree,hglobal I need to call some more methods to get the width and height of the graphic, but they are returned in "himetric" units. I have converted these to pixels. Earlier in my program, in the handling of the WM_CREATE message, I had calculated the variables xscreenpixels and yscreenpixels, using this code:
;find out the resolution of the display...
invoke GetDC, g_hwnd ;-->eax=display context client area.
mov hdc1,eax
invoke GetDeviceCaps, hdc1,LOGPIXELSX ;query pixels/inch.
mov xscreenpixels,eax
invoke GetDeviceCaps, hdc1,LOGPIXELSY ;query pixels/inch.
mov yscreenpixels,eax
invoke ReleaseDC, g_hwnd,hdc1
So, I can convert the himetric units to pixels... ;the picture is now ready to be painted... gpPicture points (indirectly) to it...
lea eax,hmwidth ;gpPicture->get_Width(&hmWidth)
push eax ;/
mov edx,dword ptr gpPicture ;/
push edx ;/
mov ecx,dword ptr [edx] ;/ (hmwidth is in himetric units)
call dword ptr [ecx 24] ;/
lea eax,hmheight ;gpPicture->get_Height(&hmHeight)
push eax ;/
mov edx,dword ptr gpPicture ;/
push edx ;/
mov ecx,dword ptr [edx] ;/
call dword ptr [ecx 28] ;/ (hmheight is in himetric units)
;the wwidth and height are in HIMETRIC units. for output to screen, need
;the width/height in pixels...
mov eax,hmwidth
mul xscreenpixels
mov ecx,2540
div ecx
mov widthpixels,eax
mov eax,hmheight
mul yscreenpixels
mov ecx,2540
div ecx
mov heightpixels,eax This section of code below is just for my own EVE program. I have an element that is to display on the screen and it has to hold gpPicture, the coordinates of the element on the diagram, and width/height in both pixels and himetric units. When EVE processes the WM_PAINT message, this info is retrieved from the element... ;the picture is going to be painted in common_paint_bitmap(), and need to
;setup the icon now and pass stuff...
mov eax,gpPicture
mov ebx,p1stdataelement
mov (OBJECT PTR [ebx]).ximage,eax
;also, save width/height of bitmap into icon...
;and update xmid/ymid...
mov edi,pobj
mov eax,widthpixels
mov (OBJECT PTR [edi]).wwidth,eax
shr eax,1
add eax,(OBJECT PTR [edi]).xtopleft
mov (OBJECT PTR [edi]).xmid,eax
mov eax,heightpixels
mov (OBJECT PTR [edi]).height,eax
shr eax,1
add eax,(OBJECT PTR [edi]).ytopleft
mov (OBJECT PTR [edi]).ymid,eax
;also need to save wwidth/height of image in 1st data-element...
mov eax,(OBJECT PTR [edi]).wwidth
mov WORD PTR (OBJECT PTR [ebx]).nshape,ax ;(alias for rplock2).
mov eax,(OBJECT PTR [edi]).height
mov WORD PTR (OBJECT PTR [ebx]).nshape 2,ax
;save the width/height in himetric units in the icon...
mov eax,hmwidth
mov (OBJECT PTR [edi]).widthhimetric,eax
mov eax,hmheight
mov (OBJECT PTR [edi]).heighthimetric,eax ok1:
xor eax,eax ;ok.
ret
er1: mov eax,219 ;error.
er0: ret
creategifhdc ENDP Ok, so we've got this gpPicture pointer and the width/height of the image, in both himetric units and pixels. When the application processes the WM_PAINT message, you can have this code: ;width/height in pixels...
mov esi,(OBJECT PTR [edi]).wwidth
mov widthpixels,esi
mov ebx,(OBJECT PTR [edi]).height
mov heightpixels,ebx
;width/height in himetric units...
mov esi,(OBJECT PTR [edi]).widthhimetric
mov widthhimetric,esi
mov ebx,(OBJECT PTR [edi]).heighthimetric
mov heighthimetric,ebx
mov ebx,p1stdataelement
mov eax,(OBJECT PTR [ebx]).ximage ;gpPicture ;hDCBitmap
mov ecx,(OBJECT PTR [edi]).xtopleft
mov edx,(OBJECT PTR [edi]).ytopleft ; // display picture using IPicture::Render
; gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
; lea ebx,clientrect
; push ebx ;0 ;really need addr of client rect here. ? (for wmf file)
push 0
mov ebx,heighthimetric ;needs to be -ve, otherwise picture
neg ebx ;displays upside down. see also below topcorner.
push ebx ;heighthimetric ;y height to copy from source picture. himetric
push widthhimetric ;x width to copy from source picture. units.
push heighthimetric ;upper-left corner of source, NOTE, not 0.
push 0 ; / himetric units.
push heightpixels ;height diagram coords.
push widthpixels ;wwidth /
push edx ;0 ;y upper-left corner,
push ecx ;0 ;x diagram coords.
push hdc ;hdc.
; mov eax,dword ptr gpPicture
push eax
mov edx,dword ptr [eax]
call dword ptr [edx 32] Ok, so as my program draws each element to the screen, it gets the gpPicture variable and the width/height parameters out. Then we call a method of the IPicture interface, called Render(). The basic structure of the code described above allows more than one picture to be simultaneously loaded and displayed. However, gpPicture points to an "interface" that points to methods (functions) as well as the actual bitmap data. So, when finished it is necessary to release the interface. My EVE program flushes these gpPicture's whenever a diagram is saved, as well as when the EVE program is exited. Here is the code to release a gpPicture interface: mov eax,(OBJECT PTR [esi]).ximage
.IF eax != 0
mov edx,eax ;gpPicture ;gpPicture->Release();
push edx ;/ "this" has to be passed, which is a ptr
mov ecx,dword ptr [edx] ;/ to the interface.
call dword ptr [ecx 8] ;/
mov (OBJECT PTR [esi]).ximage,0
.ENDIF What EVE does is look through the elements in the database, and the .ximage parameter has gpPicture if the entry is non-zero. I then call the Release() method. Simple. There you are, it works real nice. Have a look at my EVE site: http://goosee.com/ . Regards,
Barry Kauler
http://www.goosee.com/explorer *********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together!
希望能大家敞開心胸,將知識寶庫結合一起
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind
附加檔案:25823_3040.zip
|
dg822
一般會員 發表:14 回覆:38 積分:10 註冊:2004-12-16 發送簡訊給我 |
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
轉貼 http://tim.jerry.com.tw
http://tim.jerry.com.tw
上述原網站 版主所公開的源碼 【程式碼】
// ------------------------------------------------------------------------- // FileName : usingCOM.h-- , written by Kai-Hong Chen // Function : invokeMethod() , to invoke method of a object // Usage : invokeMethod(methodOffset, pObject, parameter1, parameter2, ...); // // In fact, it's really a dangerous way to invoke method, but works ! // ------------------------------------------------------------------------- stdcall invokeMethod(EBX,EAX,...); static dword returnAddress; stdcall invokeMethod(EBX,EAX,...) { ECX=EAX; EAX=DSDWORD[DSDWORD[EAX] EBX]; $pop returnAddress // pop and save the return address EAX(ECX); goto returnAddress; } // ------------------------------------------------------------------------- // FileName : TinyViewer.c-- , written by Kai-Hong Chen // Usage : left button to open a new image file, // usable keys : arrow keys, to move image // - , to enlarge or shrink // * / , best fit or auto fit // ------------------------------------------------------------------------- #pragma option w32 #jumptomain NONE #include "winbase.h--" #include "winuser.h--" #include "wingdi.h--" #include "advapi.h--" #include "commctrl.h--" #include "commdlg.h--" #include "usingCOM.h--" // for using COM object #define HIMETRIC_INCH 2540 #define MAXSIZE 260 // define method address #define Release 8 #define get_Width 24 #define get_Height 28 #define Render 32 //0x7bf80980,0xbf32,0x101a,0x8b,0xbb,0,0xaa,0,0x30,0xc,0xab dword IID_IPicture = 07bf80980h; word IID_IPicture_1 = {0bf32h,0101ah}; byte IID_IPicture_2 = {08bh,0bbh,0,0aah,0,030h,0ch,0abh}; extern WINAPI "Ole32.dll" { CreateStreamOnHGlobal(); } extern WINAPI "Olepro32.dll" { OleLoadPicture(); } HINSTANCE _hInst; HWND _hWnd; char ClassName[] = "Tiny Viewer Window Class"; char WindowsTitle[] = "Tiny Viewer"; char FilterString="All Files\x00*.*\x00"; OPENFILENAME ofn; int main() { MSG msg; _hInst = GetModuleHandle(NULL); if(!InitApplication(_hInst)) return FALSE; // register windows class if(!InitInstance(_hInst)) return FALSE; // create a windows instance while(GetMessage(#msg,NULL,0,0)) { TranslateMessage(#msg); DispatchMessage(#msg); } return msg.wParam; } BOOL InitApplication(HINSTANCE hInstance) { WNDCLASSEX wc = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = #WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = COLOR_INACTIVECAPTIONTEXT; wc.lpszClassName = #ClassName; return RegisterClassEx(#wc); } BOOL InitInstance(HINSTANCE hInstance) { _hWnd = CreateWindowEx(NULL,#ClassName,#WindowsTitle,WS_OVERLAPPEDWINDOW & !WS_MAXIMIZEBOX & !WS_THICKFRAME , CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL); if(!_hWnd) return FALSE; ShowWindow(_hWnd,SW_SHOWNORMAL); UpdateWindow(_hWnd); return TRUE; } LRESULT WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam) { static dword gpPicture = 0; static dword hmWidth,hmHeight; static int nWidth = 100,nHeight = 100; static int oWidth,oHeight; static char nameBuffer[MAXSIZE]; static int startX = 0,startY = 0; static BOOL autoAdjust = FALSE; int wmId, wmEvent; int ncSize; HDC hdc,hMemDc; PAINTSTRUCT ps; RECT rect; switch(message) { case WM_CREATE: ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = _hWnd; ofn.hInstance = _hInst; ofn.lpstrFilter = #FilterString; ofn.lpstrFile = #nameBuffer; ofn.nMaxFile = MAXSIZE; ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_HIDEREADONLY; CASE WM_LBUTTONDOWN: if(GetOpenFileName(#ofn)) { hdc = GetDC(hWnd); if(LoadPictureFile(#nameBuffer,#gpPicture) == -1) { ReleaseDC(hWnd,hdc); CenterWindow(hWnd,nWidth,nHeight); break; } startX = startY = 0; //gpPicture->get_Width(&hmWidth); //gpPicture->get_Height(&hmHeight); invokeMethod(get_Width,gpPicture,#hmWidth); invokeMethod(get_Height,gpPicture,#hmHeight); oWidth = nWidth = MulDiv(hmWidth,GetDeviceCaps(hdc,LOGPIXELSX),HIMETRIC_INCH); oHeight = nHeight = MulDiv(hmHeight,GetDeviceCaps(hdc,LOGPIXELSY),HIMETRIC_INCH); ReleaseDC(hWnd,hdc); if(autoAdjust) { SendMessage(hWnd,WM_KEYDOWN,VK_MULTIPLY,NULL); break; } } InvalidateRgn(hWnd,NULL,FALSE); CenterWindow(hWnd,nWidth,nHeight); break; case WM_KEYDOWN: if(gpPicture == 0) break; GetClientRect(hWnd,#rect); switch(wParam) { case VK_DOWN: startY = rect.bottom - nHeight; break; CASE VK_UP: startY = 0; break; CASE VK_RIGHT: startX = rect.right - nWidth; break; CASE VK_LEFT: startX = 0; break; CASE VK_SUBTRACT: nWidth = nWidth * 3 / 4; nHeight = nHeight * 3 / 4; startX = startY = 0; break; case VK_ADD: nWidth = nWidth * 4 / 3; nHeight = nHeight * 4 / 3; startX = startY = 0; break; case VK_RETURN: VKREUTRN: nWidth = oWidth; nHeight = oHeight; startX = startY = 0; break; case VK_DIVIDE: autoAdjust ^= TRUE; if(ZEROFLAG) GOTO VKREUTRN; case VK_MULTIPLY: SystemParametersInfo(SPI_GETWORKAREA,0,#rect,0); nWidth = oWidth * rect.bottom / oHeight; nHeight = rect.bottom; if(nWidth > rect.right) { nHeight = oHeight * rect.right / oWidth; nWidth = rect.right; } ncSize = CountWindowsNCSize(hWnd); nHeight -= @LOWORD(ncSize); nWidth -= @HIWORD(ncSize); startX = startY = 0; } InvalidateRgn(hWnd,NULL,FALSE); CenterWindow(hWnd,nWidth,nHeight); break; case WM_PAINT: hdc = BeginPaint(hWnd,#ps); GetClientRect(hWnd,#rect); // hMemDc = CreateCompatibleDC(hdc); // hBmp = CreateCompatibleBitmap(hdc,rect.right,rect.bottom); // SelectObject(hMemDc,hBmp); // PatBlt(hMemDc,0,0,rect.right,rect.bottom,BLACKNESS); IF(gpPicture) { //gpPicture->Render(hdc,0,0,nWidth,nHeight,0,hmHeight,hmWidth,-hmHeight,&rect); invokeMethod(Render,gpPicture,hdc,startX,startY,nWidth,nHeight,0,hmHeight,hmWidth,-hmHeight,NULL); } // BitBlt(hdc,0,0,rect.right,rect.bottom,hMemDc,0,0,SRCCOPY); // DeleteDC(hMemDc); // DeleteObject(hBmp); EndPaint(hWnd,#ps); break; case WM_DESTROY: if(gpPicture) invokeMethod(Release,gpPicture); //gpPicture->Release(); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return 0; } int LoadPictureFile(dword pszFile,ppPicture) { HANDLE hFile; unsigned int fileSize,bytesRead; dword pGlobal,pstm,saveGpPictures; hFile = CreateFile(pszFile,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); fileSize = GetFileSize(hFile,NULL); pGlobal = GlobalAlloc(GMEM_FIXED,fileSize); ReadFile(hFile,pGlobal,fileSize,#bytesRead,NULL); CloseHandle(hFile); CreateStreamOnHGlobal(pGlobal,TRUE,#pstm); saveGpPictures = DSDWORD[ppPicture]; // prevent gpPicture being broken if(saveGpPictures) invokeMethod(Release,saveGpPictures); if(OleLoadPicture(pstm,bytesRead,0,#IID_IPicture,ppPicture) != 0) { DSDWORD[ppPicture] = saveGpPictures;; MessageBoxA(0,"Image File ?", "Error", MB_OK); invokeMethod(Release,pstm); GlobalFree(pGlobal); return -1; } // pstm->Release(); invokeMethod(Release,pstm); GlobalFree(pGlobal); return 0; } CenterWindow(dword hWnd,width,height) { RECT workAreaRc; int ncSize; SystemParametersInfo(SPI_GETWORKAREA,0,#workAreaRc,0); ncSize = CountWindowsNCSize(hWnd); height = @LOWORD(ncSize); width = @HIWORD(ncSize); EAX = workAreaRc.bottom - workAreaRc.top; if(EAX < height) height = EAX; EAX = workAreaRc.right - workAreaRc.left; if(EAX < width) width = EAX; MoveWindow( hWnd, workAreaRc.right - width >> 1, workAreaRc.bottom - height >> 1, width, height, TRUE); } long CountWindowsNCSize(HANDLE hWnd) { RECT winRc,clientRc; GetWindowRect(hWnd,#winRc); GetClientRect(hWnd,#clientRc); EAX = winRc.bottom - winRc.top clientRc.top - clientRc.bottom; EBX = winRc.right - winRc.left clientRc.left - clientRc.right; return @MAKELONG(); } |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
哇!這個討論區
http://tim.jerry.com.tw/
實在是太有趣了,還有提供台語版!!
阮,還袂,會當,差無濟,罵ㄟ賽,金大,金有興趣,有何精差,一刮問題,...
真在是金醋味 < href="http://free.greenworld.com.tw/~dllee/" target="blank">吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ KTOP OpenPLC - IEC61131-3
------
http://www.ViewMove.com |
tccman
一般會員 發表:0 回覆:11 積分:2 註冊:2005-02-17 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |