diff --git a/rosapps/tests/patblt/.cvsignore b/rosapps/tests/patblt/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/patblt/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/patblt/Penguin.bmp b/rosapps/tests/patblt/Penguin.bmp new file mode 100644 index 00000000000..ec4e1daaf93 Binary files /dev/null and b/rosapps/tests/patblt/Penguin.bmp differ diff --git a/rosapps/tests/patblt/makefile b/rosapps/tests/patblt/makefile new file mode 100644 index 00000000000..cbc0b541484 --- /dev/null +++ b/rosapps/tests/patblt/makefile @@ -0,0 +1,31 @@ + +PATH_TO_TOP = ../../../reactos + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = patblt + +TARGET_NORC = yes + +TARGET_CFLAGS = -fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W -D__USE_W32API -Werror -Wall + +TARGET_CPPFLAGS = -fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W -D__USE_W32API -Wall -Werror + +TARGET_SDKLIBS = \ + kernel32.a \ + user32.a \ + gdi32.a + +TARGET_OBJECTS = \ + patblt.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# overide LD_CC to use g++ for linking of the executable +LD_CC = $(CXX) + +# EOF diff --git a/rosapps/tests/patblt/patblt.cpp b/rosapps/tests/patblt/patblt.cpp new file mode 100644 index 00000000000..84c5d7b26ac --- /dev/null +++ b/rosapps/tests/patblt/patblt.cpp @@ -0,0 +1,270 @@ + +// ------------------------------------------------------------------ +// Windows 2000 Graphics API Black Book +// Chapter 2 - Listing 2.1 (PatBlt Tracking Rect Demo) +// +// Created by Damon Chandler +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#include +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + +HINSTANCE HInst; +const char* WndClassName = "GMainWnd"; +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam); + + +int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE, LPTSTR, + int nCmdShow) +{ + HInst = HInstance; + + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.lpszClassName = WndClassName; + wc.lpfnWndProc = MainWndProc; + wc.hInstance = HInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = static_cast( + GetStockObject(BLACK_BRUSH) + ); + + if (RegisterClass(&wc)) + { + HWND HWnd = + CreateWindow(WndClassName, + TEXT("PatBlt Tracking Rect Demo"), + WS_OVERLAPPEDWINDOW | WS_CAPTION | + WS_VISIBLE | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, + NULL, NULL, HInst, NULL); + + if (HWnd) + { + ShowWindow(HWnd, nCmdShow); + UpdateWindow(HWnd); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + return 0; +} +//------------------------------------------------------------------ + + +// image related +HDC HMemDC = NULL; +HBITMAP HOldBmp = NULL; +const char* filename = "PENGUIN.BMP"; +RECT RImage = {225, 110, 225, 110}; + +// tracking related +bool is_tracking = false; +HDC HScreenDC = NULL; +POINT PMouse = {0, 0}; +RECT RTrack = {0, 0, 0, 0}; +const int line_width = 5; + + +// utility function to map to/from window coordinates +void MapRect(IN HWND HWndFrom, IN HWND HWndTo, IN OUT RECT& RMap) +{ + MapWindowPoints( + HWndFrom, HWndTo, + reinterpret_cast(&RMap), 2 + ); +} +//------------------------------------------------------------------ + + +// utility function that uses the PatBlt function to +// render a tracking rectangle +void RenderTrackingRect(IN HDC HDestDC, IN const RECT& RRender) +{ + const int width = RRender.right - RRender.left; + const int height = RRender.bottom - RRender.top; + const DWORD dwROP3 = DSTINVERT; // experiment with others + + // render top bar + PatBlt(HDestDC, + RRender.left, RRender.top, + width, line_width, + dwROP3); + // render bottom bar + PatBlt(HDestDC, + RRender.left, RRender.bottom - line_width, + width, line_width, + dwROP3); + // render left bar + PatBlt(HDestDC, + RRender.left, RRender.top + line_width, + line_width, height - (2 * line_width), + dwROP3); + // render right bar + PatBlt(HDestDC, + RRender.right - line_width, RRender.top + line_width, + line_width, height - (2 * line_width), + dwROP3); + +} +//------------------------------------------------------------------ + + +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam) +{ + switch (Msg) + { + case WM_CREATE: + { + // create a memory DC + HMemDC = CreateCompatibleDC(NULL); + if (HMemDC) + { + // load the penguin bitmap + HBITMAP HBmp = static_cast( + LoadImage(HInst, filename, IMAGE_BITMAP, 0, 0, + LR_LOADFROMFILE | LR_DEFAULTSIZE) + ); + if (HBmp) + { + // get the bitmap's dimensions + BITMAP bmp; + if (GetObject(HBmp, sizeof(BITMAP), &bmp)) + { + RImage.right += bmp.bmWidth; + RImage.bottom += bmp.bmHeight; + + // realize the bitmap + HOldBmp = static_cast( + SelectObject(HMemDC, HBmp) + ); + } + else DeleteObject(HBmp); + } + } + break; + } + case WM_LBUTTONDOWN: + { + PMouse.x = LOWORD(LParam); + PMouse.y = HIWORD(LParam); + + RECT RClient; + if (PtInRect(&RImage, PMouse) && + GetClientRect(HWnd, &RClient)) + { + MapRect(HWnd, HWND_DESKTOP, RClient); + ClipCursor(&RClient); + + // grab a handle to the screen DC and clip + // all output to the client area of our window + HScreenDC = GetDC(NULL); + HRGN HClipRgn = CreateRectRgnIndirect(&RClient); + SelectClipRgn(HScreenDC, HClipRgn); + DeleteObject(HClipRgn); + + CopyRect(&RTrack, &RImage); + MapRect(HWnd, HWND_DESKTOP, RTrack); + + // render the first tracking rect + RenderTrackingRect(HScreenDC, RTrack); + is_tracking = true; + } + break; + } + case WM_MOUSEMOVE: + { + if (HScreenDC && is_tracking) + { + POINT PCurrent = {LOWORD(LParam), HIWORD(LParam)}; + const int dX = PCurrent.x - PMouse.x; + const int dY = PCurrent.y - PMouse.y; + + // erase the previous rectangle + RenderTrackingRect(HScreenDC, RTrack); + // update the postion + OffsetRect(&RTrack, dX, dY); + // render the new tracking rectangle + RenderTrackingRect(HScreenDC, RTrack); + + // update the mouse position + memcpy(&PMouse, &PCurrent, sizeof(POINT)); + } + break; + } + case WM_LBUTTONUP: + { + // clean up + if (is_tracking) + { + is_tracking = false; + SelectClipRgn(HScreenDC, NULL); + ReleaseDC(NULL, HScreenDC); + + InvalidateRect(HWnd, &RImage, true); + CopyRect(&RImage, &RTrack); + MapRect(HWND_DESKTOP, HWnd, RImage); + InvalidateRect(HWnd, &RImage, true); + + ClipCursor(NULL); + } + break; + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC Hdc = BeginPaint(HWnd, &ps); + try + { + // + // TODO: Add palette support... + // + + // render the penguin + BitBlt(Hdc, RImage.left, RImage.top, + RImage.right - RImage.left, + RImage.bottom - RImage.top, + HMemDC, 0, 0, + SRCCOPY); + } + catch (...) + { + EndPaint(HWnd, &ps); + } + EndPaint(HWnd, &ps); + break; + } + case WM_DESTROY: + { + // clean up + if (HOldBmp) + { + DeleteObject(SelectObject(HMemDC, HOldBmp)); + } + if (HMemDC) + { + DeleteDC(HMemDC); + } + PostQuitMessage(0); + return 0; + } + } + return DefWindowProc(HWnd, Msg, WParam, LParam); +} +//------------------------------------------------------------------ diff --git a/rosapps/tests/polytest/.cvsignore b/rosapps/tests/polytest/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/polytest/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/polytest/polytest.cpp b/rosapps/tests/polytest/polytest.cpp new file mode 100644 index 00000000000..8a440cf7d5c --- /dev/null +++ b/rosapps/tests/polytest/polytest.cpp @@ -0,0 +1,874 @@ +// this is a little 'sandbox' application I put together that duplicates +// the 'guts' of the Polygon algorithm. It allows for quick turn-around +// in testing the algorithm to see what effect your changes have. +// +// Royce3 + +// the stuff immediately following is support so that the sandbox code +// is nearly identical to the real thing. +// search for the _tagFILL_EDGE struct to find the beginning of the +// real stuff. + +#include +#include +#include +#include +#include +#include + +#define FASTCALL +#define STDCALL +#define INT int +#define CLIPOBJ int +#define SURFOBJ int +#define PBRUSHOBJ int +#define MIX char +#define BOOL bool +#define TRUE true +#define FALSE false +#define CONST const +#define MmCopyFromCaller memmove +#define ALTERNATE 0 +#define WINDING 1 + +#define ASSERT assert + +typedef struct W +{ + int polyFillMode; +} W; + +typedef struct DC +{ + CLIPOBJ CombinedClip; + W w; +} DC, *PDC; + +typedef struct tagPOINT +{ + long x, y; +} POINT, *PPOINT, *LPPOINT; + +typedef struct RECTL +{ + long left, top, right, bottom; +} RECTL, *PRECTL; + +#define EngFreeMem free + +#define FL_ZERO_MEMORY 1 + +#define DPRINT1 printf("%i:",__LINE__);printf +inline void DPRINT(...){} + +#define SCREENX 25 +#define SCREENY 15 +char screen[SCREENY][SCREENX]; + +#define EDGE_CHAR '*' +#define FILL_CHAR 'o' + +void* EngAllocMem ( int zero, unsigned long size, int tag=0 ) +{ + void* p = malloc ( size ); + if ( zero ) + memset ( p, 0, size ); + return p; +} + +template +inline T MIN ( T a, T b ) +{ + return a < b ? a : b; +} + +template +inline T MAX ( T a, T b ) +{ + return a > b ? a : b; +} + +template +inline T abs ( T t ) +{ + return t < 0 ? -t : t; +} + +void putpixel ( int x, int y, char c ) +{ + ASSERT( x >= 0 && x < SCREENX && y >= 0 && y < SCREENY ); + if ( screen[y][x] == c ) + return; + if ( screen[y][x] == ' ' ) + screen[y][x] = c; + else + screen[y][x] = '#'; +} + +void IntEngLineTo ( + SURFOBJ*, + CLIPOBJ, + PBRUSHOBJ, + int x1, int y1, int x2, int y2, + RECTL*, + MIX mix ) +{ + int dx = x2 - x1; + int dy = y2 - y1; + int absdx = abs(dx); + int absdy = abs(dy); + int EMax = MAX(absdx,absdy); + int E = EMax/2; + int xinc = dx < 0 ? -1 : 1, + yinc = dy < 0 ? -1 : 1; + if ( !dy ) + { + while ( x1 != x2 ) + { + putpixel ( x1, y1, mix ); + x1 += xinc; + } + return; + } + if ( !dx ) + { + while ( y1 != y2 ) + { + putpixel ( x1, y1, mix ); + y1 += yinc; + } + return; + } + for ( int i = 0; i < EMax; i++ ) + { + putpixel ( x1, y1, mix ); + if ( absdy > absdx ) + { + y1 += yinc; + E += absdx; + if ( E >= EMax ) + { + E -= absdy; + x1 += xinc; + } + } + else + { + x1 += xinc; + E += absdy; + if ( E >= EMax ) + { + E -= absdx; + y1 += yinc; + } + } + } +} + +#define FILL_EDGE_ALLOC_TAG 0x45465044 + +/* +** This struct is used for book keeping during polygon filling routines. +*/ +typedef struct _tagFILL_EDGE +{ + /*Basic line information*/ + int FromX; + int FromY; + int ToX; + int ToY; + int dx; + int dy; + int absdx, absdy; + int x, y; + int xmajor; + + /*Active Edge List information*/ + int XIntercept[2]; + int Error; + int ErrorMax; + int XDirection, YDirection; + + /* The next edge in the active Edge List*/ + struct _tagFILL_EDGE * pNext; +} FILL_EDGE; + +typedef struct _FILL_EDGE_LIST +{ + int Count; + FILL_EDGE** Edges; +} FILL_EDGE_LIST; + +#if 0 +static +void +DEBUG_PRINT_ACTIVE_EDGELIST ( FILL_EDGE* list ) +{ + FILL_EDGE* pThis = list; + if (0 == list) + { + DPRINT1("List is NULL\n"); + return; + } + + while(0 != pThis) + { + //DPRINT1("EDGE: (%d, %d) to (%d, %d)\n", pThis->FromX, pThis->FromY, pThis->ToX, pThis->ToY); + DPRINT1("EDGE: [%d,%d]\n", pThis->XIntercept[0], pThis->XIntercept[1] ); + pThis = pThis->pNext; + } +} +#else +#define DEBUG_PRINT_ACTIVE_EDGELIST(x) +#endif + +/* +** Hide memory clean up. +*/ +static +void +FASTCALL +POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST* list) +{ + int i; + if ( list ) + { + if ( list->Edges ) + { + for ( i = 0; i < list->Count; i++ ) + { + if ( list->Edges[i] ) + EngFreeMem ( list->Edges[i] ); + } + EngFreeMem ( list->Edges ); + } + EngFreeMem ( list ); + } +} + +/* +** This makes and initiaizes an Edge struct for a line between two points. +*/ +static +FILL_EDGE* +FASTCALL +POLYGONFILL_MakeEdge(POINT From, POINT To) +{ + FILL_EDGE* rc = (FILL_EDGE*)EngAllocMem(FL_ZERO_MEMORY, sizeof(FILL_EDGE), FILL_EDGE_ALLOC_TAG); + + if (0 == rc) + return NULL; + + //DPRINT1("Making Edge: (%d, %d) to (%d, %d)\n", From.x, From.y, To.x, To.y); + //Now Fill the struct. + if ( To.y < From.y ) + { + rc->FromX = To.x; + rc->FromY = To.y; + rc->ToX = From.x; + rc->ToY = From.y; + rc->YDirection = -1; + + // lines that go up get walked backwards, so need to be offset + // by -1 in order to make the walk identically on a pixel-level + rc->Error = -1; + } + else + { + rc->FromX = From.x; + rc->FromY = From.y; + rc->ToX = To.x; + rc->ToY = To.y; + rc->YDirection = 1; + + rc->Error = 0; + } + + rc->x = rc->FromX; + rc->y = rc->FromY; + rc->dx = rc->ToX - rc->FromX; + rc->dy = rc->ToY - rc->FromY; + rc->absdx = abs(rc->dx); + rc->absdy = abs(rc->dy); + + rc->xmajor = rc->absdx > rc->absdy; + + rc->ErrorMax = MAX(rc->absdx,rc->absdy); + + rc->Error += rc->ErrorMax / 2; + + rc->XDirection = (rc->dx < 0)?(-1):(1); + + rc->pNext = 0; + + DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n", + From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax ); + + return rc; +} +/* +** My Edge comparison routine. +** This is for scan converting polygon fill. +** First sort by MinY, then Minx, then slope. +** +** This comparison will help us determine which +** lines will become active first when scanning from +** top (min y) to bottom (max y). +** +** Return Value Meaning +** Negative integer element1 < element2 +** Zero element1 = element2 +** Positive integer element1 > element2 +*/ +static +INT +FASTCALL +FILL_EDGE_Compare(FILL_EDGE* Edge1, FILL_EDGE* Edge2) +{ + int e1 = Edge1->XIntercept[0] + Edge1->XIntercept[1]; + int e2 = Edge2->XIntercept[0] + Edge2->XIntercept[1]; + + return e1 - e2; +} + + +/* +** Insert an edge into a list keeping the list in order. +*/ +static +void +FASTCALL +POLYGONFILL_ActiveListInsert(FILL_EDGE** activehead, FILL_EDGE* NewEdge ) +{ + FILL_EDGE *pPrev, *pThis; + //DPRINT1("In POLYGONFILL_ActiveListInsert()\n"); + ASSERT ( activehead && NewEdge ); + if ( !*activehead ) + { + NewEdge->pNext = NULL; + *activehead = NewEdge; + return; + } + /* + ** First lets check to see if we have a new smallest value. + */ + if (FILL_EDGE_Compare(NewEdge, *activehead) <= 0) + { + NewEdge->pNext = *activehead; + *activehead = NewEdge; + return; + } + /* + ** Ok, now scan to the next spot to put this item. + */ + pThis = *activehead; + pPrev = NULL; + while ( pThis && FILL_EDGE_Compare(pThis, NewEdge) < 0 ) + { + pPrev = pThis; + pThis = pThis->pNext; + } + + ASSERT(pPrev); + NewEdge->pNext = pPrev->pNext; + pPrev->pNext = NewEdge; + //DEBUG_PRINT_ACTIVE_EDGELIST(*activehead); +} + +/* +** Create a list of edges for a list of points. +*/ +static +FILL_EDGE_LIST* +FASTCALL +POLYGONFILL_MakeEdgeList(PPOINT Points, int Count) +{ + int CurPt = 0; + FILL_EDGE_LIST* list = 0; + FILL_EDGE* e = 0; + + if ( 0 == Points || 2 > Count ) + return 0; + + list = (FILL_EDGE_LIST*)EngAllocMem(FL_ZERO_MEMORY, sizeof(FILL_EDGE_LIST), FILL_EDGE_ALLOC_TAG); + if ( 0 == list ) + goto fail; + list->Count = 0; + list->Edges = (FILL_EDGE**)EngAllocMem(FL_ZERO_MEMORY, Count*sizeof(FILL_EDGE*), FILL_EDGE_ALLOC_TAG); + if ( !list->Edges ) + goto fail; + memset ( list->Edges, 0, Count * sizeof(FILL_EDGE*) ); + + for ( CurPt = 1; CurPt < Count; ++CurPt ) + { + e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[CurPt] ); + if ( !e ) + goto fail; + // if a straight horizontal line - who cares? + if ( !e->absdy ) + EngFreeMem ( e ); + else + list->Edges[list->Count++] = e; + } + e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[0] ); + if ( !e ) + goto fail; + if ( !e->absdy ) + EngFreeMem ( e ); + else + list->Edges[list->Count++] = e; + return list; + +fail: + DPRINT1("Out Of MEMORY!!\n"); + POLYGONFILL_DestroyEdgeList ( list ); + return 0; +} + + +/* +** This slow routine uses the data stored in the edge list to +** calculate the x intercepts for each line in the edge list +** for scanline Scanline. +**TODO: Get rid of this floating point arithmetic +*/ +static +void +FASTCALL +POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) +{ + if ( 0 == pEdge->dy ) + return; + + ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY > Scanline ); + + if ( pEdge->xmajor ) + { + int steps; + + ASSERT ( pEdge->y == Scanline ); + + // now shoot to end of scanline collision + steps = (pEdge->ErrorMax-pEdge->Error-1)/pEdge->absdy; + if ( steps ) + { + // record first collision with scanline + int x1 = pEdge->x; + pEdge->x += steps * pEdge->XDirection; + pEdge->Error += steps * pEdge->absdy; + ASSERT ( pEdge->Error < pEdge->ErrorMax ); + pEdge->XIntercept[0] = MIN(x1,pEdge->x); + pEdge->XIntercept[1] = MAX(x1,pEdge->x); + } + else + { + pEdge->XIntercept[0] = pEdge->x; + pEdge->XIntercept[1] = pEdge->x; + } + + // we should require exactly 1 step to step onto next scanline... + ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 ); + pEdge->x += pEdge->XDirection; + pEdge->Error += pEdge->absdy; + ASSERT ( pEdge->Error >= pEdge->ErrorMax ); + + // now step onto next scanline... + pEdge->Error -= pEdge->absdx; + pEdge->y++; + } + else // then this is a y-major line + { + pEdge->XIntercept[0] = pEdge->x; + pEdge->XIntercept[1] = pEdge->x; + + pEdge->Error += pEdge->absdx; + pEdge->y++; + + if ( pEdge->Error >= pEdge->ErrorMax ) + { + pEdge->Error -= pEdge->ErrorMax; + pEdge->x += pEdge->XDirection; + ASSERT ( pEdge->Error < pEdge->ErrorMax ); + } + } + + DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n", + pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] ); +} + +/* +** This method updates the Active edge collection for the scanline Scanline. +*/ +static +void +STDCALL +POLYGONFILL_BuildActiveList ( int Scanline, FILL_EDGE_LIST* list, FILL_EDGE** ActiveHead ) +{ + int i; + + ASSERT ( list && ActiveHead ); + *ActiveHead = 0; + for ( i = 0; i < list->Count; i++ ) + { + FILL_EDGE* pEdge = list->Edges[i]; + ASSERT(pEdge); + if ( pEdge->FromY <= Scanline && pEdge->ToY > Scanline ) + { + POLYGONFILL_UpdateScanline ( pEdge, Scanline ); + POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge ); + } + } +} + +/* +** This method fills the portion of the polygon that intersects with the scanline +** Scanline. +*/ +static +void +STDCALL +POLYGONFILL_FillScanLineAlternate( + PDC dc, + int ScanLine, + FILL_EDGE* ActiveHead, + SURFOBJ *SurfObj, + PBRUSHOBJ BrushObj, + MIX RopMode ) +{ + FILL_EDGE *pLeft, *pRight; + + if ( !ActiveHead ) + return; + + pLeft = ActiveHead; + pRight = pLeft->pNext; + ASSERT(pRight); + + while ( NULL != pRight ) + { + int x1 = pLeft->XIntercept[0]; + int x2 = pRight->XIntercept[1]; + if ( x2 > x1 ) + { + RECTL BoundRect; + BoundRect.top = ScanLine; + BoundRect.bottom = ScanLine + 1; + BoundRect.left = x1; + BoundRect.right = x2; + + DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX + } + pLeft = pRight->pNext; + pRight = pLeft ? pLeft->pNext : NULL; + } +} + +static +void +STDCALL +POLYGONFILL_FillScanLineWinding( + PDC dc, + int ScanLine, + FILL_EDGE* ActiveHead, + SURFOBJ *SurfObj, + PBRUSHOBJ BrushObj, + MIX RopMode ) +{ + FILL_EDGE *pLeft, *pRight; + int x1, x2, winding = 0; + RECTL BoundRect; + + if ( !ActiveHead ) + return; + + BoundRect.top = ScanLine; + BoundRect.bottom = ScanLine + 1; + + pLeft = ActiveHead; + winding = pLeft->YDirection; + pRight = pLeft->pNext; + ASSERT(pRight); + + // setup first line... + x1 = pLeft->XIntercept[0]; + x2 = pRight->XIntercept[1]; + + pLeft = pRight; + pRight = pLeft->pNext; + winding += pLeft->YDirection; + + while ( NULL != pRight ) + { + int newx1 = pLeft->XIntercept[0]; + int newx2 = pRight->XIntercept[1]; + if ( winding ) + { + // check and see if this new line touches the previous... + if ( (newx1 >= x1 && newx1 <= x2) + || (newx2 >= x1 && newx2 <= x2) + || (x1 >= newx1 && x1 <= newx2) + || (x2 >= newx2 && x2 <= newx2) + ) + { + // yup, just tack it on to our existing line + x1 = MIN(x1,newx1); + x2 = MAX(x2,newx2); + } + else + { + // nope - render the old line.. + BoundRect.left = x1; + BoundRect.right = x2; + + DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX + + x1 = newx1; + x2 = newx2; + } + } + pLeft = pRight; + pRight = pLeft->pNext; + winding += pLeft->YDirection; + } + // there will always be a line left-over, render it now... + BoundRect.left = x1; + BoundRect.right = x2; + + DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); + IntEngLineTo( SurfObj, + dc->CombinedClip, + BrushObj, + x1, + ScanLine, + x2, + ScanLine, + &BoundRect, // Bounding rectangle + RopMode); // MIX +} + +//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and +//even-numbered polygon sides on each scan line. That is, GDI fills the area between the +//first and second side, between the third and fourth side, and so on. + +//WINDING Selects winding mode (fills any region with a nonzero winding value). +//When the fill mode is WINDING, GDI fills any region that has a nonzero winding value. +//This value is defined as the number of times a pen used to draw the polygon would go around the region. +//The direction of each edge of the polygon is important. + +BOOL +STDCALL +FillPolygon( + PDC dc, + SURFOBJ *SurfObj, + PBRUSHOBJ BrushObj, + MIX RopMode, + CONST PPOINT Points, + int Count, + RECTL BoundRect ) +{ + FILL_EDGE_LIST *list = 0; + FILL_EDGE *ActiveHead = 0; + int ScanLine; + + void + STDCALL + (*FillScanLine)( + PDC dc, + int ScanLine, + FILL_EDGE* ActiveHead, + SURFOBJ *SurfObj, + PBRUSHOBJ BrushObj, + MIX RopMode ); + + DPRINT("FillPolygon\n"); + + /* Create Edge List. */ + list = POLYGONFILL_MakeEdgeList(Points, Count); + /* DEBUG_PRINT_EDGELIST(list); */ + if (NULL == list) + return FALSE; + + if ( WINDING == dc->w.polyFillMode ) + FillScanLine = POLYGONFILL_FillScanLineWinding; + else /* default */ + FillScanLine = POLYGONFILL_FillScanLineAlternate; + + /* For each Scanline from BoundRect.bottom to BoundRect.top, + * determine line segments to draw + */ + for ( ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine ) + { + POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead); + //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead); + FillScanLine ( dc, ScanLine, ActiveHead, SurfObj, BrushObj, RopMode ); + } + + /* Free Edge List. If any are left. */ + POLYGONFILL_DestroyEdgeList(list); + + return TRUE; +} + + + + + +// this is highly hacked from W32kPolygon... +BOOL +Polygon ( CONST PPOINT UnsafePoints, int Count, int polyFillMode ) +{ + BOOL ret; + RECTL DestRect; + int CurrentPoint; + PPOINT Points; + SURFOBJ* SurfObj = 0; + DC dc; + PBRUSHOBJ OutBrushObj = 0; + + dc.CombinedClip = 0; + dc.w.polyFillMode = polyFillMode; + + DPRINT1("In W32kPolygon()\n"); + + if ( NULL == UnsafePoints || Count < 2) + { + DPRINT1("ERROR_INVALID_PARAMETER\n"); + return FALSE; + } + + /* Copy points from userspace to kernelspace */ + Points = (PPOINT)EngAllocMem(0, Count * sizeof(POINT)); + if (NULL == Points) + { + DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n"); + return FALSE; + } + MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT)); + if ( memcmp ( Points, UnsafePoints, Count * sizeof(POINT) ) ) + { + free(Points); + return FALSE; + } + + DestRect.left = Points[0].x; + DestRect.right = Points[0].x; + DestRect.top = Points[0].y; + DestRect.bottom = Points[0].y; + + for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint) + { + DestRect.left = MIN(DestRect.left, Points[CurrentPoint].x); + DestRect.right = MAX(DestRect.right, Points[CurrentPoint].x); + DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y); + DestRect.bottom = MAX(DestRect.bottom, Points[CurrentPoint].y); + } + + // Draw the Polygon Edges with the current pen + for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint) + { + POINT To, From; //, Next; + + /* Let CurrentPoint be i + * if i+1 > Count, Draw a line from Points[i] to Points[0] + * Draw a line from Points[i] to Points[i+1] + */ + From = Points[CurrentPoint]; + if ( CurrentPoint + 1 >= Count) + { + To = Points[0]; + } + else + { + To = Points[CurrentPoint + 1]; + } + + DPRINT1("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y ); + IntEngLineTo(SurfObj, + dc.CombinedClip, + OutBrushObj, + From.x, + From.y, + To.x, + To.y, + &DestRect, + EDGE_CHAR); /* MIX */ + } + /* determine the fill mode to fill the polygon. */ + ret = FillPolygon(&dc, SurfObj, OutBrushObj, FILL_CHAR, Points, Count, DestRect ); + free(Points); + + return ret; +} + + +int main() +{ + memset ( screen, ' ', sizeof(screen) ); + POINT pts[] = + { +#if 0 + { 0, 0 }, + { 12, 4 }, + { 4, 8 }, +#elif 0 + { 3, 0 }, + { 0, 3 }, + { 3, 6 }, +#elif 0 + { 1, 1 }, + { 3, 1 }, + { 3, 3 }, + { 1, 3 } +#elif 0 + { 0, 0 }, + { 4, 0 }, + { 4, 4 }, + { 8, 4 }, + { 8, 8 }, + { 4, 8 }, + { 4, 4 }, + { 0, 4 }, +#else + { 4, 12 }, + { 12, 0 }, + { 18, 12 }, + { 4, 4 }, + { 20, 4 } +#endif + }; + const int pts_count = sizeof(pts)/sizeof(pts[0]); + + // use ALTERNATE or WINDING for 3rd param + Polygon ( pts, pts_count, ALTERNATE ); + + // print out our "screen" + for ( int y = 0; y < SCREENY; y++ ) + { + for ( int x = 0; x < SCREENX; x++ ) + { + printf("%c", screen[y][x] ); + } + printf("\n"); + } + DPRINT1("Done!\n"); + (void)getch(); +} +/* EOF */ diff --git a/rosapps/tests/polytest/polytest.dsp b/rosapps/tests/polytest/polytest.dsp new file mode 100644 index 00000000000..8151a7c682e --- /dev/null +++ b/rosapps/tests/polytest/polytest.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="polytest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=polytest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "polytest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "polytest.mak" CFG="polytest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "polytest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "polytest - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "polytest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "polytest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "polytest - Win32 Release" +# Name "polytest - Win32 Debug" +# Begin Source File + +SOURCE=.\polytest.cpp +# End Source File +# End Target +# End Project diff --git a/rosapps/tests/polytest/polytest.dsw b/rosapps/tests/polytest/polytest.dsw new file mode 100644 index 00000000000..c09be21753b --- /dev/null +++ b/rosapps/tests/polytest/polytest.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "polytest"=".\polytest.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/rosapps/tests/popupmenu/.cvsignore b/rosapps/tests/popupmenu/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/popupmenu/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/popupmenu/makefile b/rosapps/tests/popupmenu/makefile new file mode 100644 index 00000000000..b05f3cb1ee3 --- /dev/null +++ b/rosapps/tests/popupmenu/makefile @@ -0,0 +1,23 @@ +# $Id: makefile,v 1.1 2004/10/21 04:53:20 sedwards Exp $ + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = no + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = popupmenu + +TARGET_SDKLIBS = kernel32.a gdi32.a user32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/popupmenu/popupmenu.c b/rosapps/tests/popupmenu/popupmenu.c new file mode 100644 index 00000000000..e6a33c2e4f5 --- /dev/null +++ b/rosapps/tests/popupmenu/popupmenu.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include "resource.h" + +LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); + +int WINAPI +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + WNDCLASS wc; + MSG msg; + HWND hWnd; + + wc.lpszClassName = "MenuTestClass"; + wc.lpfnWndProc = MainWndProc; + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszMenuName = (LPCTSTR)IDM_MAINMENU; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + if (RegisterClass(&wc) == 0) + { + fprintf(stderr, "RegisterClass failed (last error 0x%lX)\n", + GetLastError()); + return(1); + } + + hWnd = CreateWindow("MenuTestClass", + "PopupMenu Test", + WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hInstance, + NULL); + if (hWnd == NULL) + { + fprintf(stderr, "CreateWindow failed (last error 0x%lX)\n", + GetLastError()); + return(1); + } + + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return msg.wParam; +} + +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDM_EXIT: + PostQuitMessage(0); + break; + } + break; + } + case WM_RBUTTONUP: + { + POINT pos; + HMENU Menu; + + pos.x = LOWORD(lParam); + pos.y = HIWORD(lParam); + ClientToScreen(hWnd, &pos); + + if((Menu = GetMenu(hWnd)) && (Menu = GetSubMenu(Menu, 1))) + { + TrackPopupMenu(Menu, 0, pos.x, pos.y, 0, hWnd, NULL); + } + break; + } + case WM_DESTROY: + { + PostQuitMessage(0); + break; + } + default: + { + return DefWindowProc(hWnd, msg, wParam, lParam); + } + } + return 0; +} diff --git a/rosapps/tests/popupmenu/popupmenu.rc b/rosapps/tests/popupmenu/popupmenu.rc new file mode 100644 index 00000000000..9c4af8b0542 --- /dev/null +++ b/rosapps/tests/popupmenu/popupmenu.rc @@ -0,0 +1,47 @@ +#include +#include +#include "resource.h" + +IDM_MAINMENU MENU LOADONCALL MOVEABLE DISCARDABLE +{ + POPUP "&File" + { + MENUITEM "&New\tCtrl+N", 1 + MENUITEM "&Open\tCtrl+O", 2 + POPUP "Open &Recent" + { + MENUITEM "&1", 11 + MENUITEM "&2", 12 + MENUITEM "&3", 13 + MENUITEM "&4", 14 + MENUITEM "&5", 15 + MENUITEM "&6", 16 + MENUITEM "&7", 17 + MENUITEM "&8", 18 + MENUITEM "&9", 19 + } + MENUITEM SEPARATOR + MENUITEM "&Save\tCtrl+S", 3 + MENUITEM "Save &as...", 4 + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt-F4", IDM_EXIT + } + POPUP "&Edit" + { + MENUITEM "&Undo\tCtrl+Z", 20 + MENUITEM "&Redo\tShift+Ctrl+Z", 21 + MENUITEM SEPARATOR + MENUITEM "&Cut\tCtrl+X", 22 + MENUITEM "&Copy\tCtrl+C", 23 + MENUITEM "&Paste\tCtrl+V", 24 + MENUITEM SEPARATOR + MENUITEM "Select &all", 25 + MENUITEM "&Delete\tDel", 26 + } + POPUP "&Help" + { + MENUITEM "&Help Topics\tF1", 30 + MENUITEM SEPARATOR + MENUITEM "&About...", 31 + } +} diff --git a/rosapps/tests/popupmenu/resource.h b/rosapps/tests/popupmenu/resource.h new file mode 100644 index 00000000000..b4929dbf2d2 --- /dev/null +++ b/rosapps/tests/popupmenu/resource.h @@ -0,0 +1,2 @@ +#define IDM_MAINMENU 101 +#define IDM_EXIT 199 diff --git a/rosapps/tests/primitives/.cvsignore b/rosapps/tests/primitives/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/primitives/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/primitives/Makefile b/rosapps/tests/primitives/Makefile new file mode 100644 index 00000000000..61e8b4cc06a --- /dev/null +++ b/rosapps/tests/primitives/Makefile @@ -0,0 +1,37 @@ +# +# ReactOS explorer +# +# Makefile +# + +PATH_TO_TOP = ../../../reactos + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = primitives + +TARGET_NORC = yes + +TARGET_CFLAGS = -fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W -D__USE_W32API -Wall -Werror + +TARGET_CPPFLAGS = -fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W -D__USE_W32API -Wall -Werror + +TARGET_SDKLIBS = \ + kernel32.a \ + user32.a \ + gdi32.a + +TARGET_OBJECTS = \ + primitives.o \ + mk_font.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# overide LD_CC to use g++ for linking of the executable +LD_CC = $(CXX) + +# EOF diff --git a/rosapps/tests/primitives/mk_font.cpp b/rosapps/tests/primitives/mk_font.cpp new file mode 100644 index 00000000000..59e3cf8ca93 --- /dev/null +++ b/rosapps/tests/primitives/mk_font.cpp @@ -0,0 +1,69 @@ + +// ------------------------------------------------------------------ +// Windows 2000 Graphics API Black Book +// Chapter 4 - Utility functions +// +// Created by Damon Chandler +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#include +#include + +#include "mk_font.h" +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +namespace font { + +// creates a logical font +HFONT MakeFont( + IN HDC hDestDC, // handle to target DC + IN LPCSTR typeface_name, // font's typeface name + IN int point_size, // font's point size + IN const BYTE charset, // font's character set + IN const DWORD style // font's styles + ) +{ + // + // NOTE: On Windows 9x/Me, GetWorldTransform is not + // supported. For compatibility with these platforms you + // should initialize the XFORM::eM22 data member to 1.0. + // + XFORM xf = {0, 0, 0, 1.0, 0, 0}; + GetWorldTransform(hDestDC, &xf); + int pixels_per_inch = GetDeviceCaps(hDestDC, LOGPIXELSY); + + POINT PSize = { + 0, + -MulDiv(static_cast(xf.eM22 * point_size + 0.5), + pixels_per_inch, 72) + }; + + HFONT hResult = NULL; + if (DPtoLP(hDestDC, &PSize, 1)) + { + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + + lf.lfHeight = PSize.y; + lf.lfCharSet = charset; + lstrcpyn(reinterpret_cast(&lf.lfFaceName), + typeface_name, LF_FACESIZE); + + lf.lfWeight = (style & FS_BOLD) ? FW_BOLD : FW_DONTCARE; + lf.lfItalic = (style & FS_ITALIC) ? true : false; + lf.lfUnderline = (style & FS_UNDERLINE) ? true : false; + lf.lfStrikeOut = (style & FS_STRIKEOUT) ? true : false; + + // create the logical font + hResult = CreateFontIndirect(&lf); + } + return hResult; +} +//------------------------------------------------------------------------- + +} // namespace font diff --git a/rosapps/tests/primitives/mk_font.h b/rosapps/tests/primitives/mk_font.h new file mode 100644 index 00000000000..98c164c9f1d --- /dev/null +++ b/rosapps/tests/primitives/mk_font.h @@ -0,0 +1,39 @@ + +// ------------------------------------------------------------------ +// Windows 2000 Graphics API Black Book +// Chapter 4 - Utility functions +// +// Created by Damon Chandler +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#ifndef CH4_UTILS_H +#define CH4_UTILS_H + +#include +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +// change namespace name appropriately to suit your needs +namespace font { + +// font options +static const ULONG FS_NONE = 0x00000000; +static const ULONG FS_BOLD = 0x00000001; +static const ULONG FS_ITALIC = 0x00000002; +static const ULONG FS_UNDERLINE = 0x00000004; +static const ULONG FS_STRIKEOUT = 0x00000008; + +// creates a logical font +HFONT MakeFont(IN HDC hDestDC, IN LPCSTR typeface_name, + IN int point_size, IN const BYTE charset = ANSI_CHARSET, + IN const DWORD style = FS_NONE); + +} + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#endif // CH4_UTILS_H +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff --git a/rosapps/tests/primitives/primitives.cpp b/rosapps/tests/primitives/primitives.cpp new file mode 100644 index 00000000000..1a3499967ac --- /dev/null +++ b/rosapps/tests/primitives/primitives.cpp @@ -0,0 +1,351 @@ + +// ------------------------------------------------------------------ +// Windows 2000 Graphics API Black Book +// Chapter 5 - Listing 5.1 (Output Primitives Demo) +// +// Created by Damon Chandler +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#include +#include + +// for the MakeFont() function... +#include "mk_font.h" +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + +HINSTANCE hInst; +const char* WndClassName = "GMainWnd"; +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam); + + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, + int nCmdShow) +{ + hInst = hInstance; + + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.lpszClassName = WndClassName; + wc.lpfnWndProc = MainWndProc; + wc.hInstance = hInst; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = reinterpret_cast( + COLOR_BTNFACE + 1 + ); + + if (RegisterClass(&wc)) + { + HWND hWnd = + CreateWindow( + WndClassName, TEXT("Output Primitives Demo"), + WS_OVERLAPPEDWINDOW | WS_CAPTION | + WS_VISIBLE | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, + NULL, NULL, hInst, NULL + ); + + if (hWnd) + { + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + return 0; +} +//------------------------------------------------------------------ + + +enum OutPrimitive { + opLine, opBezier, opRectangle, opRoundRect, + opEllipse, opArc, opPie, opChord, opCustom + }; + +void DrawPrimitive(IN HDC hDC, IN const RECT& RPrimitive, + IN OutPrimitive PrimitiveID) +{ + RECT R = RPrimitive; + InflateRect(&R, -10, -10); + + switch (PrimitiveID) + { + case opLine: + { + const POINT PLine[] = {{R.left, R.top}, {R.right, R.bottom}}; + Polyline(hDC, PLine, 2); + break; + } + case opBezier: + { + const POINT PControlPoints[] = { + {R.left, R.top}, + {(R.right - R.left) / 2, R.top}, + {(R.right - R.left) / 2, R.bottom}, + {R.right, R.bottom} + }; + PolyBezier(hDC, PControlPoints, 4); + break; + } + case opRectangle: + { + Rectangle(hDC, R.left, R.top, R.right, R.bottom); + break; + } + case opRoundRect: + { + RoundRect(hDC, R.left, R.top, R.right, R.bottom, 20, 20); + break; + } + case opEllipse: + { + Ellipse(hDC, R.left, R.top, R.right, R.bottom); + break; + } + case opArc: + { + const POINT PRads[] = { + {(R.right - R.left) / 3 + R.left, R.top}, + {(R.right - R.left) / 3 + R.left, R.bottom} + }; + Arc(hDC, R.left, R.top, R.right, R.bottom, + PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y); + break; + } + case opPie: + { + const POINT PRads[] = { + {(R.right - R.left) / 3 + R.left, R.top}, + {(R.right - R.left) / 3 + R.left, R.bottom} + }; + Pie(hDC, R.left, R.top, R.right, R.bottom, + PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y); + break; + } + case opChord: + { + const POINT PRads[] = { + {(R.right - R.left) / 3 + R.left, R.top}, + {(R.right - R.left) / 3 + R.left, R.bottom} + }; + Chord(hDC, R.left, R.top, R.right, R.bottom, + PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y); + break; + } + case opCustom: + { + const POINT PVertices[] = { + {R.left, (R.bottom - R.top) / 2 + R.top}, + {(R.right - R.left) / 2 + R.left, R.top}, + {R.right, (R.bottom - R.top) / 2 + R.top}, + {(R.right - R.left) / 2 + R.left, R.bottom} + }; + Polygon(hDC, PVertices, 4); + break; + } + } +} +//------------------------------------------------------------------ + + +HWND hListBox = NULL; // handle to the list box +HBRUSH hListBrush = NULL; // handle to the list box brush +HPEN hListPen = NULL; // handle to the list box pen +HFONT hListFont = NULL; // handle to the list box font + +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + switch (msg) + { + case WM_CREATE: + { + hListBox = + CreateWindowEx( + WS_EX_CLIENTEDGE, TEXT("LISTBOX"), TEXT(""), + WS_CHILD | WS_VISIBLE | WS_VSCROLL | + LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | + LBS_OWNERDRAWFIXED, + 0, 0, 640, 480, + hWnd, NULL, hInst, NULL + ); + assert(hListBox != NULL); + + SetWindowLong( + hListBox, GWL_ID, reinterpret_cast(hListBox) + ); + + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Line"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Bezier Curve"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Rectangle"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Rounded Rectangle"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Ellipse"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Arc"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Pie Slice"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Chord"))); + SNDMSG(hListBox, LB_ADDSTRING, 0, + reinterpret_cast(TEXT("Custom"))); + + hListBrush = CreateSolidBrush(PALETTERGB(64, 192, 64)); + hListPen = CreatePen(PS_SOLID, 3, PALETTERGB(0, 0, 0)); + HDC hScreenDC = GetDC(NULL); +#if 0 + try +#endif + { + // MakeFont() from Chapter 4 + hListFont = font::MakeFont( + hScreenDC, "Impact", 20, ANSI_CHARSET, + font::FS_BOLD | font::FS_UNDERLINE + ); + } +#if 0 + catch (...) +#endif + { + ReleaseDC(NULL, hScreenDC); + } + ReleaseDC(NULL, hScreenDC); + + break; + } + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lpmis = + reinterpret_cast(lParam); + assert(lpmis != NULL); + + if (lpmis->CtlID == reinterpret_cast(hListBox)) + { + lpmis->itemHeight = 150; + return TRUE; + } + break; + } + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis = + reinterpret_cast(lParam); + assert(lpdis != NULL); + + if (lpdis->CtlID == reinterpret_cast(hListBox)) + { + SaveDC(lpdis->hDC); +#if 0 + try +#endif + { + SelectObject(lpdis->hDC, hListBrush); + SelectObject(lpdis->hDC, hListPen); + SelectObject(lpdis->hDC, hListFont); + + bool selected = (lpdis->itemState & ODS_SELECTED); + COLORREF clrText = GetSysColor( + selected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT + ); + HBRUSH hListBrush = GetSysColorBrush( + selected ? COLOR_HIGHLIGHT : COLOR_WINDOW + ); + + // fill the background + FillRect(lpdis->hDC, &lpdis->rcItem, hListBrush); + + // render the output primitive + RECT RPrimitive = lpdis->rcItem; + InflateRect(&RPrimitive, -5, -5); + RPrimitive.right = static_cast( + 0.6 * lpdis->rcItem.right + 0.5 + ); + FillRect( + lpdis->hDC, &RPrimitive, + reinterpret_cast(COLOR_BTNFACE + 1) + ); + DrawPrimitive( + lpdis->hDC, RPrimitive, + static_cast(lpdis->itemID) + ); + if (selected) InvertRect(lpdis->hDC, &RPrimitive); + DrawEdge(lpdis->hDC, &RPrimitive, EDGE_SUNKEN, BF_RECT); + + // render the text + TCHAR text[13]; + if (SNDMSG(hListBox, LB_GETTEXT, lpdis->itemID, + reinterpret_cast(&text)) != LB_ERR) + { + RECT RText = RPrimitive; + RText.left = RPrimitive.right; + RText.right = lpdis->rcItem.right; + + SelectObject(lpdis->hDC, hListFont); + SetBkMode(lpdis->hDC, TRANSPARENT); + SetTextColor(lpdis->hDC, clrText); + + DrawText(lpdis->hDC, text, -1, &RText, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + } + + // indicate keyboard focus + if (lpdis->itemState & ODS_FOCUS) + { + RECT RFocus = lpdis->rcItem; + InflateRect(&RFocus, -1, -1); + DrawFocusRect(lpdis->hDC, &RFocus); + } + } +#if 0 + catch (...) +#endif + { + RestoreDC(lpdis->hDC, -1); + } + RestoreDC(lpdis->hDC, -1); + return TRUE; + } + break; + } + case WM_SIZE: + { + MoveWindow( + hListBox, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE + ); + return 0; + } + case WM_DESTROY: + { + if (hListBrush) DeleteObject(hListBrush); + if (hListPen) DeleteObject(hListPen); + if (hListFont) DeleteObject(hListFont); + + PostQuitMessage(0); + return 0; + } + } + return DefWindowProc(hWnd, msg, wParam, lParam); +} +//------------------------------------------------------------------------- + + + diff --git a/rosapps/tests/pteb/.cvsignore b/rosapps/tests/pteb/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/pteb/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/pteb/Makefile b/rosapps/tests/pteb/Makefile new file mode 100644 index 00000000000..cd9645de040 --- /dev/null +++ b/rosapps/tests/pteb/Makefile @@ -0,0 +1,23 @@ +# $Id: Makefile,v 1.1 2004/10/21 04:53:21 sedwards Exp $ + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = pteb + +TARGET_SDKLIBS = ntdll.a kernel32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/pteb/pteb.c b/rosapps/tests/pteb/pteb.c new file mode 100644 index 00000000000..f91a2c16981 --- /dev/null +++ b/rosapps/tests/pteb/pteb.c @@ -0,0 +1,23 @@ +#include +#include + + +int main(int argc, char* argv[]) +{ + int x; + PTEB Teb; + + printf("TEB dumpper\n"); + __asm__("movl %%fs:0x18, %0\n\t" + : "=a" (x) + : /* no inputs */); + printf("fs[0x18] %x\n", x); + + Teb = (PTEB)x; + + printf("StackBase: 0x%08lX\n", (DWORD)Teb->Tib.StackBase); + printf("StackLimit: 0x%08lX\n", (DWORD)Teb->Tib.StackLimit); + printf("DeallocationStack: 0x%08lX\n", (DWORD)Teb->DeallocationStack); + + return(0); +} diff --git a/rosapps/tests/regqueryvalue/.cvsignore b/rosapps/tests/regqueryvalue/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/regqueryvalue/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/regqueryvalue/makefile b/rosapps/tests/regqueryvalue/makefile new file mode 100644 index 00000000000..bb90ae85e1c --- /dev/null +++ b/rosapps/tests/regqueryvalue/makefile @@ -0,0 +1,22 @@ + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = regqueryvalue + +TARGET_SDKLIBS = advapi32.a ws2_32.a kernel32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror -g + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/regqueryvalue/regqueryvalue.c b/rosapps/tests/regqueryvalue/regqueryvalue.c new file mode 100644 index 00000000000..008d8c3ec81 --- /dev/null +++ b/rosapps/tests/regqueryvalue/regqueryvalue.c @@ -0,0 +1,69 @@ +#define _DISABLE_TIDENTS +#include +#include +#include +#include +#include + +int main( int argc, char **argv ) { + ULONG ResultSize; + PWCHAR WcharResult; + WCHAR ValueNameWC[100]; + PCHAR CharResult; + HANDLE RegKey; + int i; + + if( argc < 2 ) { + printf( "Usage: regqueryvalue [key] [value]\n" ); + printf( "Returns an HKEY_LOCAL_MACHINE value from the given key.\n" ); + return 1; + } + + if ( RegOpenKeyExA( HKEY_LOCAL_MACHINE, argv[1], 0, KEY_READ, &RegKey ) + != 0 ) { + printf( "Could not open key %s\n", argv[1] ); + return 2; + } + + for( i = 0; argv[2][i]; i++ ) ValueNameWC[i] = argv[2][i]; + ValueNameWC[i] = 0; + + if(RegQueryValueExW( RegKey, ValueNameWC, NULL, NULL, NULL, &ResultSize ) + != 0) { + printf( "The value %S does not exist.\n", ValueNameWC ); + return 5; + } + + WcharResult = malloc( (ResultSize + 1) * sizeof(WCHAR) ); + + if( !WcharResult ) { + printf( "Could not alloc %d wchars\n", (int)(ResultSize + 1) ); + return 6; + } + + RegQueryValueExW( RegKey, ValueNameWC, NULL, NULL, (LPBYTE)WcharResult, + &ResultSize ); + + printf( "wchar Value: %S\n", WcharResult ); + fflush( stdout ); + + RegQueryValueExA( RegKey, argv[2], NULL, NULL, NULL, &ResultSize ); + + CharResult = malloc( ResultSize + 1 ); + + if( !CharResult ) { + printf( "Could not alloc %d chars\n", (int)(ResultSize + 1) ); + return 7; + } + + RegQueryValueExA( RegKey, argv[2], NULL, NULL, CharResult, &ResultSize ); + + printf( " char Value: %s\n", CharResult ); + fflush( stdout ); + + free( WcharResult ); + free( CharResult ); + free( ValueNameWC ); + + return 0; +} diff --git a/rosapps/tests/regtest/.cvsignore b/rosapps/tests/regtest/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/regtest/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/regtest/makefile b/rosapps/tests/regtest/makefile new file mode 100644 index 00000000000..e8b423e7e2d --- /dev/null +++ b/rosapps/tests/regtest/makefile @@ -0,0 +1,24 @@ +# +# $Id: makefile,v 1.1 2004/10/21 04:53:21 sedwards Exp $ + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = regtest + +TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/regtest/regtest.c b/rosapps/tests/regtest/regtest.c new file mode 100644 index 00000000000..ca867d2b10a --- /dev/null +++ b/rosapps/tests/regtest/regtest.c @@ -0,0 +1,995 @@ +#include +#include +#include +#include +#include +#include + +HANDLE OutputHandle; +HANDLE InputHandle; + +void dprintf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + + va_start(args,fmt); + vsprintf(buffer,fmt,args); + WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); + va_end(args); +} + +void do_enumeratekey(PWSTR Name) +{ + ULONG Index,Length,i; + KEY_BASIC_INFORMATION KeyInformation[5]; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hKey1; + UNICODE_STRING KeyName; + + RtlInitUnicodeString(&KeyName, Name); + InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE + , NULL, NULL); + Status=NtOpenKey( &hKey1, MAXIMUM_ALLOWED, &ObjectAttributes); + dprintf("NtEnumerateKey : \n"); + Index=0; + while(Status == STATUS_SUCCESS) + { + Status=NtEnumerateKey(hKey1,Index++,KeyBasicInformation + ,&KeyInformation[0], sizeof(KeyInformation) + ,&Length); + if(Status== STATUS_SUCCESS) + { + dprintf("\tSubKey Name = "); + for (i=0;i +#include +#include + +int main(int argc, char* argv[]) +{ + HANDLE hFile; + HANDLE Section; + PVOID BaseAddress; + + printf("Section Test\n"); + + hFile = CreateFile(_T("sectest.txt"), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + 0, + 0); + if (hFile == INVALID_HANDLE_VALUE) + { + printf("Failed to create file (err=%ld)", GetLastError()); + return 1; + } + + Section = CreateFileMapping(hFile, + NULL, + PAGE_READWRITE, + 0, + 4096, + NULL); + if (Section == NULL) + { + printf("Failed to create section (err=%ld)", GetLastError()); + return 1; + } + + printf("Mapping view of section\n"); + BaseAddress = MapViewOfFile(Section, + FILE_MAP_ALL_ACCESS, + 0, + 0, + 4096); + printf("BaseAddress %x\n", (UINT) BaseAddress); + if (BaseAddress == NULL) + { + printf("Failed to map section (%ld)\n", GetLastError()); + return 1; + } + + printf("Clearing section\n"); + FillMemory(BaseAddress, 4096, ' '); + printf("Copying test data to section\n"); + strcpy(BaseAddress, "test data"); + + if (!UnmapViewOfFile(BaseAddress)) + { + printf("Failed to unmap view of file (%ld)\n", GetLastError()); + return 1; + } + + if (!CloseHandle(hFile)) + { + printf("Failed to close file (%ld)\n", GetLastError()); + return 1; + } + + return 0; +} + diff --git a/rosapps/tests/sertest/.cvsignore b/rosapps/tests/sertest/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/sertest/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/sertest/makefile b/rosapps/tests/sertest/makefile new file mode 100644 index 00000000000..1b72105cd03 --- /dev/null +++ b/rosapps/tests/sertest/makefile @@ -0,0 +1,24 @@ +# +# $Id: makefile,v 1.0 + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = sertest + +TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/sertest/sertest.c b/rosapps/tests/sertest/sertest.c new file mode 100644 index 00000000000..e6d7c4eae1e --- /dev/null +++ b/rosapps/tests/sertest/sertest.c @@ -0,0 +1,131 @@ +#include +#include + +#define BUFSIZE 128 +#define MAX_PORTNAME_LEN 20 +#define APP_VERSION_STR "0.01" + +int main(int argc, char *argv[]) +{ + CHAR txBuffer[BUFSIZE]; + CHAR rxBuffer[BUFSIZE]; + DWORD dwBaud = 9600; + DWORD dwNumWritten; + DWORD dwErrors; + DCB dcb; + BOOL bResult; + HANDLE hPort; + int i; + int j; + int k; + int nPortNum = 1; + + TCHAR szPortName[MAX_PORTNAME_LEN]; + + if (argc > 1) { + //sscanf(argv[1], "%d", &dwBaud); + sscanf(argv[1], "%d", &nPortNum); + } + sprintf(szPortName, _T("COM%d"), nPortNum); + + printf("Serial Port Test Application Version %s\n", APP_VERSION_STR); + printf("Attempting to open serial port %d - %s\n", nPortNum, szPortName); + hPort = CreateFile(szPortName, + GENERIC_READ|GENERIC_WRITE, + 0, // exclusive + NULL, // sec attr + OPEN_EXISTING, + 0, // no attributes + NULL); // no template + + if (hPort == (HANDLE)-1) { + printf("ERROR: CreateFile() failed with result: %lx\n", (DWORD)hPort); + return 1; + } + printf("CreateFile() returned: %lx\n", (DWORD)hPort); + + printf("Fiddling with DTR and RTS control lines...\n"); + for (i = 0; i < 100; i++) { + bResult = EscapeCommFunction(hPort, SETDTR); + if (!bResult) { + printf("WARNING: EscapeCommFunction(SETDTR) failed: %lx\n", (DWORD)bResult); + } + bResult = EscapeCommFunction(hPort, SETRTS); + if (!bResult) { + printf("WARNING: EscapeCommFunction(SETRTS) failed: %lx\n", (DWORD)bResult); + } + for (j = 0; j < 1000; j++) { + k *= j; + } +/* +#define CLRDTR (6) +#define CLRRTS (4) +#define SETDTR (5) +#define SETRTS (3) +#define SETXOFF (1) +#define SETXON (2) +#define SETBREAK (8) +#define CLRBREAK (9) + */ + bResult = EscapeCommFunction(hPort, CLRDTR); + if (!bResult) { + printf("WARNING: EscapeCommFunction(CLRDTR) failed: %lx\n", (DWORD)bResult); + } + bResult = EscapeCommFunction(hPort, CLRRTS); + if (!bResult) { + printf("WARNING: EscapeCommFunction(CLRRTS) failed: %lx\n", (DWORD)bResult); + } + } + printf("Getting the default line characteristics...\n"); + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hPort, &dcb)) { + printf("ERROR: failed to get the dcb: %ld\n", GetLastError()); + return 2; + } + printf("Setting the line characteristics to 9600,8,N,1\n"); + dcb.BaudRate = dwBaud; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + + bResult = SetCommState(hPort, &dcb); + if (!bResult) { + printf("ERROR: failed to set the comm state: %lx\n", (DWORD)bResult); + return 3; + } + for (i = 0; i < BUFSIZE; i++) { + txBuffer[i] = (CHAR)i; + //printf(" %d ", txBuffer[i]); + rxBuffer[i] = 0xFF; + } + printf("\n"); + printf("Writting transmit buffer to the serial port\n"); + bResult = WriteFile(hPort, txBuffer, BUFSIZE, &dwNumWritten, NULL); + if (!bResult) { + printf("ERROR: failed to write to the serial port: %lx\n", (DWORD)bResult); + return 4; + } + printf("WriteFile() returned: %lx, byteswritten: %lx\n", (DWORD)bResult, dwNumWritten); +#if 0 + printf("Attempting to read %d bytes from the serial port\n", BUFSIZE); + bResult = ReadFile(hPort, rxBuffer, BUFSIZE, &dwNumRead, NULL); + if (!bResult) { + printf("ERROR: failed to read from the serial port: %lx\n", (DWORD)bResult); + return 5; + } + printf("ReadFile() returned: %lx, bytesread: %lx\n", (DWORD)bResult, dwNumRead); + for (i = 0; i < BUFSIZE; i++) { + printf(" %d ",rxBuffer[i]); + } +#endif + printf("Attempting to close the serial port\n"); + bResult = ClearCommError(hPort, &dwErrors, NULL); + printf("ClearCommError returned: %lx, dwErrors: %lx\n", (DWORD)bResult, dwErrors); + bResult = CloseHandle(hPort); + if (!bResult) { + printf("ERROR: failed to close the serial port: %lx\n", (DWORD)bResult); + return 6; + } + printf("Finished\n"); + return 0; +} diff --git a/rosapps/tests/shaptest/.cvsignore b/rosapps/tests/shaptest/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/shaptest/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/shaptest/makefile b/rosapps/tests/shaptest/makefile new file mode 100644 index 00000000000..c04849721a6 --- /dev/null +++ b/rosapps/tests/shaptest/makefile @@ -0,0 +1,25 @@ +# $Id: makefile,v 1.1 2004/10/21 04:53:21 sedwards Exp $ + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = shaptest + +TARGET_CFLAGS = -Wall -Werror + +TARGET_SDKLIBS = kernel32.a gdi32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/shaptest/shaptest.c b/rosapps/tests/shaptest/shaptest.c new file mode 100644 index 00000000000..693cfc3f184 --- /dev/null +++ b/rosapps/tests/shaptest/shaptest.c @@ -0,0 +1,252 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * AUTHOR: See gditest-- (initial changes by Mark Tempel) + * shaptest + * + * This is a windowed application that should draw two polygons. One + * is drawn with ALTERNATE fill, the other is drawn with WINDING fill. + * This is used to test out the Polygon() implementation. + */ + +#include +#include +#include + +#ifndef ASSERT +#define ASSERT assert +#endif + +#define nelem(x) (sizeof (x) / sizeof *(x)) + +HFONT tf; +LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); + +void PolygonTest ( HDC hdc ) +{ + HPEN Pen, OldPen; + HBRUSH RedBrush, OldBrush; + DWORD Mode; + POINT PointsAlternate[] = + { + { 20, 80 }, + { 60, 20 }, + { 90, 80 }, + { 20, 40 }, + { 100, 40 } + }; + POINT PointsWinding[] = + { + { 130, 80 }, + { 170, 20 }, + { 200, 80 }, + { 130, 40 }, + { 210, 40 } + }; + POINT Tri1[] = + { + { 3, 3 }, + { 5, 3 }, + { 3, 5 } + }; + POINT Tri2[] = + { + { 7, 3 }, + { 7, 7 }, + { 3, 7 }, + }; + POINT Square1[] = + { + { 1, 15 }, + { 3, 15 }, + { 3, 17 }, + { 1, 17 } + }; + POINT Square2[] = + { + { 5, 15 }, + { 7, 15 }, + { 7, 17 }, + { 5, 17 } + }; + POINT Square3[] = + { + { 1, 23 }, + { 3, 23 }, + { 3, 25 }, + { 1, 25 } + }; + POINT Square4[] = + { + { 5, 23 }, + { 7, 23 }, + { 7, 25 }, + { 5, 25 } + }; + POINT Square5[] = + { + { 1, 31 }, + { 3, 31 }, + { 3, 33 }, + { 1, 33 } + }; + POINT Square6[] = + { + { 5, 31 }, + { 7, 31 }, + { 7, 33 }, + { 5, 33 } + }; + + //create a pen to draw the shape + Pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff)); + ASSERT(Pen); + RedBrush = CreateSolidBrush(RGB(0xff, 0, 0)); + ASSERT(RedBrush); + + OldPen = (HPEN)SelectObject(hdc, Pen); + OldBrush = (HBRUSH)SelectObject(hdc, RedBrush); + + Mode = GetPolyFillMode(hdc); + + RoundRect ( hdc, 32, 8, 48, 24, 8, 8 ); + + SetPolyFillMode(hdc, ALTERNATE); + Polygon(hdc,PointsAlternate,nelem(PointsAlternate)); + + SetPolyFillMode(hdc, WINDING); + Polygon(hdc,PointsWinding,nelem(PointsWinding)); + + Rectangle ( hdc, 1, 1, 10, 10 ); + Polygon(hdc,Tri1,nelem(Tri1)); + Polygon(hdc,Tri2,nelem(Tri2)); + + Rectangle ( hdc, 1, 11, 4, 14 ); + Rectangle ( hdc, 5, 11, 8, 14 ); + Rectangle ( hdc, 9, 11, 12, 14 ); + Rectangle ( hdc, 13, 11, 16, 14 ); + Polygon(hdc,Square1,nelem(Square1)); + Polygon(hdc,Square2,nelem(Square2)); + Rectangle ( hdc, 1, 19, 4, 22 ); + Rectangle ( hdc, 5, 19, 8, 22 ); + Rectangle ( hdc, 9, 19, 12, 22 ); + Rectangle ( hdc, 13, 19, 16, 22 ); + Polygon(hdc,Square3,nelem(Square3)); + Polygon(hdc,Square4,nelem(Square4)); + Rectangle ( hdc, 1, 27, 4, 30 ); + Rectangle ( hdc, 5, 27, 8, 30 ); + Rectangle ( hdc, 9, 27, 12, 30 ); + Rectangle ( hdc, 13, 27, 16, 30 ); + + // switch to null pen to make surey they display correctly + DeleteObject ( SelectObject(hdc, OldPen) ); + Pen = CreatePen ( PS_NULL, 0, 0 ); + ASSERT(Pen); + OldPen = (HPEN)SelectObject(hdc, Pen); + + Polygon(hdc,Square5,nelem(Square5)); + Polygon(hdc,Square6,nelem(Square6)); + Rectangle ( hdc, 1, 35, 4, 38 ); + Rectangle ( hdc, 5, 35, 8, 38 ); + Rectangle ( hdc, 9, 35, 12, 38 ); + Rectangle ( hdc, 13, 35, 16, 38 ); + + //cleanup + SetPolyFillMode(hdc, Mode); + DeleteObject ( SelectObject(hdc, OldPen) ); + DeleteObject ( SelectObject(hdc, OldBrush) ); +} + + +void shaptest( HDC hdc ) +{ + //Test the Polygon routine. + PolygonTest(hdc); +} + + +int WINAPI +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + WNDCLASS wc; + MSG msg; + HWND hWnd; + + wc.lpszClassName = "ShapTestClass"; + wc.lpfnWndProc = MainWndProc; + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.hInstance = hInstance; + wc.hIcon = (HICON)LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + wc.hCursor = (HCURSOR)LoadCursor(NULL, (LPCTSTR)IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + if (RegisterClass(&wc) == 0) + { + fprintf(stderr, "RegisterClass failed (last error 0x%X)\n", + (unsigned int)GetLastError()); + return(1); + } + + hWnd = CreateWindow("ShapTestClass", + "Shaptest", + WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, + 0, + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hInstance, + NULL); + if (hWnd == NULL) + { + fprintf(stderr, "CreateWindow failed (last error 0x%X)\n", + (unsigned int)GetLastError()); + return(1); + } + + tf = CreateFontA(14, 0, 0, TA_BASELINE, FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "Timmons"); + + ShowWindow(hWnd, nCmdShow); + + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + DeleteObject(tf); + + return msg.wParam; +} + +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT ps; + HDC hDC; + + switch(msg) + { + + case WM_PAINT: + hDC = BeginPaint(hWnd, &ps); + shaptest( hDC ); + EndPaint(hWnd, &ps); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + return 0; +} + diff --git a/rosapps/tests/statst/.cvsignore b/rosapps/tests/statst/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/statst/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/statst/Makefile b/rosapps/tests/statst/Makefile new file mode 100644 index 00000000000..e3e1a087996 --- /dev/null +++ b/rosapps/tests/statst/Makefile @@ -0,0 +1,21 @@ +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = statst + +TARGET_SDKLIBS = kernel32.a gdi32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/statst/statst.c b/rosapps/tests/statst/statst.c new file mode 100644 index 00000000000..080b77baddb --- /dev/null +++ b/rosapps/tests/statst/statst.c @@ -0,0 +1,165 @@ +//#define WIN32_LEAN_AND_MEAN +#include + +static LPSTR STATIC_CLASS = "STATIC"; +static LPSTR TEST_WND_CLASS = "TESTWND"; + +#ifdef NDEBUG + #define DPRINT(s) (void)0 +#else + #define DPRINT(s) OutputDebugStringA("STATICTEST: " s "\n") +#endif + +HINSTANCE AppInstance = NULL; + +LRESULT WmCreate( + HWND Wnd) +{ + UCHAR i; + DPRINT("WM_CREATE (enter)."); + // Test 1 - black rectangle. + DPRINT("test 1"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE | SS_BLACKRECT, + 10, 10, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 2 - black frame. + DPRINT("test 2"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE | SS_BLACKFRAME, + 10, 40, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 3 - gray rectangle. + DPRINT("test 3"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE | SS_GRAYRECT, + 10, 70, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 4 - gray frame. + DPRINT("test 4"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE | SS_GRAYFRAME, + 10, 100, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 5 - left-aligned text. + DPRINT("test 5"); + CreateWindowEx(0, STATIC_CLASS, + "&Left-aligned text &static control window", + WS_CHILD | WS_VISIBLE | SS_LEFT, + 10, 130, 100, 50, Wnd, NULL, AppInstance, NULL); + // Test 6 - right-aligned text. + DPRINT("test 6"); + CreateWindowEx(0, STATIC_CLASS, + "&Right-aligned text &static control window", + WS_CHILD | WS_VISIBLE | SS_RIGHT, + 10, 185, 100, 50, Wnd, NULL, AppInstance, NULL); + // Test 7 - centered text. + DPRINT("test 7"); + CreateWindowEx(0, STATIC_CLASS, + "&Centered text &static control window", + WS_CHILD | WS_VISIBLE | SS_CENTER, + 10, 240, 100, 50, Wnd, NULL, AppInstance, NULL); + // Test 8 - left-aligned text with no word wrap and no prefixes. + DPRINT("test 8"); + CreateWindowEx(0, STATIC_CLASS, + "&No prefix and no word wrapping", + WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP | SS_NOPREFIX, + 10, 295, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 9 - white rectangle. + DPRINT("test 9"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE | SS_WHITERECT, + 120, 10, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 10 - white frame. + DPRINT("test 10"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE | SS_WHITEFRAME, + 120, 40, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 11 - etched frame. + DPRINT("test 11"); + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE + | SS_ETCHEDFRAME, 120, 70, 100, 20, Wnd, NULL, AppInstance, NULL); + // Test 12 - etched horizontal lines. + DPRINT("test 12"); + for (i = 0; i < 5; ++i) + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE + | SS_ETCHEDHORZ, 120, 100 + (4L * i), 100, 4, Wnd, + NULL, AppInstance, NULL); + // Test 13 - etched vertical lines. + DPRINT("test 13"); + for (i = 0; i < 25; ++i) + CreateWindowEx(0, STATIC_CLASS, NULL, WS_CHILD | WS_VISIBLE + | SS_ETCHEDVERT, 120 + (4L * i), 130, 4, 20, Wnd, + NULL, AppInstance, NULL); + // Test 14 - sunken border. + DPRINT("test 14"); + CreateWindowEx(0, STATIC_CLASS, + "Sunken frame and word ellipsis", + WS_CHILD | WS_VISIBLE | SS_SUNKEN | SS_WORDELLIPSIS, + 120, 160, 100, 20, Wnd, NULL, AppInstance, NULL); + DPRINT("WM_CREATE (leave)."); + return 0; +} + +LRESULT CALLBACK TestWndProc( + HWND Wnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam) +{ + switch (Msg) { + case WM_CREATE: + return WmCreate(Wnd); + case WM_DESTROY: + PostQuitMessage(0); + return 0; + default: + return DefWindowProc(Wnd, Msg, wParam, lParam); + } +} + +int STDCALL WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd) +{ + ATOM Result; + MSG Msg; + HWND MainWindow; + WNDCLASSEX TestWndClass = {0}; + DPRINT("Application starting up."); + // Remember instance handle. + AppInstance = GetModuleHandle(NULL); + // Register test window class. + TestWndClass.cbSize = sizeof(WNDCLASSEX); + TestWndClass.lpfnWndProc = &TestWndProc; + TestWndClass.hInstance = AppInstance; + TestWndClass.hCursor = LoadCursor(0, (LPCTSTR)IDC_ARROW); + TestWndClass.hbrBackground = CreateSolidBrush(RGB(255,255,230)); + TestWndClass.lpszClassName = TEST_WND_CLASS; + Result = RegisterClassEx(&TestWndClass); + if (Result == 0) { + DPRINT("Error registering class."); + MessageBox(0, "Error registering test window class.", + "Static control test", MB_ICONSTOP | MB_OK); + ExitProcess(0); + } + // Create main window. + DPRINT("Creating main window."); + MainWindow = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_CLIENTEDGE, + TEST_WND_CLASS, "Static control test", + WS_OVERLAPPEDWINDOW, 50, 50, 245, 365, + NULL, NULL, AppInstance, NULL); + if (MainWindow == 0) { + DPRINT("Error creating main window."); + UnregisterClass(TEST_WND_CLASS, AppInstance); + MessageBox(0, "Error creating test window.", + "Static control test", MB_ICONSTOP | MB_OK); + ExitProcess(0); + } + DPRINT("Showing main window."); + ShowWindow(MainWindow, SW_SHOWNORMAL); + UpdateWindow(MainWindow); + // Run message loop. + DPRINT("Entering message loop."); + while (GetMessage(&Msg, NULL, 0, 0) > 0) { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + // Unregister window class. + UnregisterClass(TEST_WND_CLASS, AppInstance); + DPRINT("Exiting."); + + return Msg.wParam; +} diff --git a/rosapps/tests/statst2/.cvsignore b/rosapps/tests/statst2/.cvsignore new file mode 100644 index 00000000000..060f7fa87a2 --- /dev/null +++ b/rosapps/tests/statst2/.cvsignore @@ -0,0 +1,7 @@ +*.o +*.d +*.a +*.exe +*.coff +*.sym +*.map \ No newline at end of file diff --git a/rosapps/tests/statst2/Makefile b/rosapps/tests/statst2/Makefile new file mode 100644 index 00000000000..452d2aa46e6 --- /dev/null +++ b/rosapps/tests/statst2/Makefile @@ -0,0 +1,22 @@ + +PATH_TO_TOP = ../../../reactos + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = statst2 + +TARGET_SDKLIBS = kernel32.a gdi32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/rosapps/tests/statst2/statst2.c b/rosapps/tests/statst2/statst2.c new file mode 100644 index 00000000000..6ac769ed38b --- /dev/null +++ b/rosapps/tests/statst2/statst2.c @@ -0,0 +1,180 @@ +// Static Control Test.c + +//#define WIN32_LEAN_AND_MEAN +#include +#include + +#ifndef SS_ENDELLIPSIS +#define SS_ENDELLIPSIS 0x00004000L +#endif /* SS_ENDELLIPSIS */ + + +#define nMaxCtrls 32 +#define nStaticWidth 384 +#define nStaticHeight 18 + +HWND g_hwnd = NULL; +HINSTANCE g_hInst = 0; +int nNextCtrl = 0; +HWND g_hwndCtrl[nMaxCtrls]; + +static void CreateStatic ( const char* lpWindowName, DWORD dwStyle ) +{ + int n = nNextCtrl++; + assert ( n < nMaxCtrls ); + g_hwndCtrl[n] = CreateWindow ( + "STATIC", // lpClassName + lpWindowName, // lpWindowName + WS_VISIBLE|WS_CHILD|dwStyle, // dwStyle + n+2, // x + nStaticHeight*n+1, // y + nStaticWidth, // nWidth + nStaticHeight-1, // nHeight + g_hwnd, // hWndParent + NULL, // hMenu + g_hInst, // hInstance + NULL ); // lParam +} + +LRESULT CALLBACK WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + int i; + switch ( msg ) + { + case WM_CREATE: + g_hwnd = hwnd; + for ( i = 0; i < nMaxCtrls; i++ ) + g_hwndCtrl[i] = NULL; + + CreateStatic ( "SS_NOTIFY test (click/double-click here)", SS_NOTIFY ); + + CreateStatic ( "SS_ENDELLIPSIS test test test test test test test test test test test", SS_ENDELLIPSIS ); + + CreateStatic ( "SS_CENTER test", SS_CENTER ); + + CreateStatic ( "SS_RIGHT test", SS_RIGHT ); + + CreateStatic ( "SS_BLACKFRAME test:", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_BLACKFRAME ); + + CreateStatic ( "SS_BLACKRECT test:", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_BLACKRECT ); + + CreateStatic ( "SS_ETCHEDFRAME test:", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_ETCHEDFRAME ); + + CreateStatic ( "SS_ETCHEDHORZ test:", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_ETCHEDHORZ ); + + CreateStatic ( "SS_ETCHEDVERT test", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_ETCHEDVERT ); + + CreateStatic ( "SS_GRAYFRAME test", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_GRAYFRAME ); + + CreateStatic ( "SS_GRAYRECT test", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_GRAYRECT ); + + CreateStatic ( "SS_NOPREFIX &test", SS_NOPREFIX ); + + CreateStatic ( "SS_OWNERDRAW test", SS_OWNERDRAW ); + + CreateStatic ( "SS_SUNKEN test", SS_SUNKEN ); + + CreateStatic ( "SS_WHITEFRAME test:", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_WHITEFRAME ); + + CreateStatic ( "SS_WHITERECT test:", 0 ); + CreateStatic ( "this text shouldn't be visible!", SS_WHITERECT ); + + //if ( creation fails ) + // return 0; + break; + + case WM_COMMAND: + if ( HIWORD(wParam) == STN_CLICKED ) + SetWindowText ( (HWND)lParam, "SS_NOTIFY:STN_CLICKED!" ); + if ( HIWORD(wParam) == STN_DBLCLK ) + SetWindowText ( (HWND)lParam, "SS_NOTIFY:STN_DBLCLK!" ); + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT) lParam; + DrawText ( lpDrawItem->hDC, "SS_DRAWITEM test successful!", 28, &(lpDrawItem->rcItem), 0 ); + } + break; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + return DefWindowProc ( hwnd, msg, wParam, lParam ); +} + +HWND RegisterAndCreateWindow ( + HINSTANCE hInst, + const char* className, + const char* title ) +{ + WNDCLASSEX wc; + HWND hwnd; + + g_hInst = hInst; + + wc.cbSize = sizeof (WNDCLASSEX); + wc.lpfnWndProc = WndProc; // window procedure: mandatory + wc.hInstance = hInst; // owner of the class: mandatory + wc.lpszClassName = className; // mandatory + wc.hCursor = LoadCursor ( 0, (LPCTSTR)IDC_ARROW ); // optional + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // optional + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIcon = 0; + wc.hIconSm = 0; + wc.lpszMenuName = 0; + if ( !RegisterClassEx ( &wc ) ) + return NULL; + + hwnd = CreateWindowEx ( + 0, // dwStyleEx + className, // class name + title, // window title + WS_OVERLAPPEDWINDOW, // dwStyle + CW_USEDEFAULT, // x + CW_USEDEFAULT, // y + CW_USEDEFAULT, // width + CW_USEDEFAULT, // height + NULL, // hwndParent + NULL, // hMenu + hInst, // hInstance + 0 ); // lParam + + if ( !hwnd ) + return NULL; + + ShowWindow ( hwnd, SW_SHOW ); + UpdateWindow ( hwnd ); + + return hwnd; +} + +int WINAPI WinMain ( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow ) +{ + char className [] = "Static Control Test"; + HWND hwnd; + MSG msg; + int status; + + hwnd = RegisterAndCreateWindow ( hInst, className, "Static Control Test" ); + + // Message loop + while ((status = GetMessage (& msg, 0, 0, 0)) != 0) + { + if (status == -1) + return -1; + DispatchMessage ( &msg ); + } + return msg.wParam; +} diff --git a/rosapps/tests/stretchblt/lena.bmp b/rosapps/tests/stretchblt/lena.bmp new file mode 100644 index 00000000000..e9916963852 Binary files /dev/null and b/rosapps/tests/stretchblt/lena.bmp differ