Example #1
0
gxFont *gxGraphics::loadFont( const string &f,int height,int flags ){

	int bold=flags & gxFont::FONT_BOLD ? FW_BOLD : FW_REGULAR;
	int italic=flags & gxFont::FONT_ITALIC ? 1 : 0;
	int underline=flags & gxFont::FONT_UNDERLINE ? 1 : 0;
	int strikeout=0;

	string t;
	int n=f.find('.');
	if( n!=string::npos ){
		t=fullfilename(f);
		if( !font_res.count(t) && AddFontResource( t.c_str() ) ) font_res.insert( t );
		t=filenamefile( f.substr(0,n) );
	}else{
		t=f;
	}

	//save and turn off font smoothing....
	BOOL smoothing=FALSE;
	SystemParametersInfo( SPI_GETFONTSMOOTHING,0,&smoothing,0 );
	SystemParametersInfo( SPI_SETFONTSMOOTHING,FALSE,0,0 );

	HFONT hfont=CreateFont( 
		height,0,0,0,
		bold,italic,underline,strikeout,
		ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
		DEFAULT_PITCH|FF_DONTCARE,t.c_str() );

	if( !hfont ){
		//restore font smoothing
		SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
		return 0;
	}

	HDC hdc=CreateCompatibleDC( 0 );
	HFONT pfont=(HFONT)SelectObject( hdc,hfont );

	TEXTMETRIC tm={0};
	if( !GetTextMetrics( hdc,&tm ) ){
		SelectObject( hdc,pfont );
		DeleteDC( hdc );
		DeleteObject( hfont );
		SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
		return 0;
	}
	height=tm.tmHeight;

	int first=tm.tmFirstChar,last=tm.tmLastChar;
	int sz=last-first+1;
	int *offs=d_new int[sz];
	int *widths=d_new int[sz];
	int *as=d_new int[sz];

	//calc size of canvas to hold font.
	int x=0,y=0,max_x=0;
	for( int k=0;k<sz;++k ){

		char t=k+first;

		SIZE sz;
		GetTextExtentPoint32( hdc,&t,1,&sz );
		int w=sz.cx;

		as[k]=0;

		ABC abc;
		if( GetCharABCWidths( hdc,t,t,&abc ) ){
			if( abc.abcA<0 ){
				as[k]=ceil(-abc.abcA);
				w+=as[k];
			}
			if( abc.abcC<0 ) w+=ceil(-abc.abcC);
		}

		if( x && x+w>getWidth() ){ x=0;y+=height; }
		offs[k]=(x<<16)|y;
		widths[k]=w;
		x+=w;if( x>max_x ) max_x=x;
	}
	SelectObject( hdc,pfont );
	DeleteDC( hdc );

	int cw=max_x,ch=y+height;

	if( gxCanvas *c=createCanvas( cw,ch,0 ) ){
		ddSurf *surf=c->getSurface();

		HDC surf_hdc;
		if( surf->GetDC( &surf_hdc )>=0 ){
			HFONT pfont=(HFONT)SelectObject( surf_hdc,hfont );

			SetBkColor( surf_hdc,0x000000 );
			SetTextColor( surf_hdc,0xffffff );

			for( int k=0;k<sz;++k ){
				int x=(offs[k]>>16)&0xffff,y=offs[k]&0xffff;
				char t=k+first;
				RECT rect={x,y,x+widths[k],y+height};
				ExtTextOut( surf_hdc,x+as[k],y,ETO_CLIPPED,&rect,&t,1,0 );
			}

			SelectObject( surf_hdc,pfont );
			surf->ReleaseDC( surf_hdc );
			DeleteObject( hfont );
			delete[] as;

			c->backup();
			gxFont *font=d_new gxFont( this,c,tm.tmMaxCharWidth,height,first,last+1,tm.tmDefaultChar,offs,widths );
			font_set.insert( font );

			//restore font smoothing
			SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
			return font;
		}else{
Example #2
0
int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
{
    int i = 0;
    int glyph_pos = 0;
    if (mirrored) {
#if defined(Q_WS_WINCE)
        {
#else
        if (symbol) {
            for (; i < numChars; ++i, ++glyph_pos) {
                unsigned int uc = getChar(str, i, numChars);
                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
                if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
            }
        } else if (ttf) {
            for (; i < numChars; ++i, ++glyph_pos) {
                unsigned int uc = getChar(str, i, numChars);
                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, QChar::mirroredChar(uc));
            }
        } else {
#endif
            wchar_t first = tm.tmFirstChar;
            wchar_t last = tm.tmLastChar;

            for (; i < numChars; ++i, ++glyph_pos) {
                uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
                if (
#ifdef Q_WS_WINCE
                    tm.tmFirstChar > 60000 || // see line 375
#endif
                        ucs >= first && ucs <= last)
                    glyphs->glyphs[glyph_pos] = ucs;
                else
                    glyphs->glyphs[glyph_pos] = 0;
            }
        }
    } else {
#if defined(Q_WS_WINCE)
        {
#else
        if (symbol) {
            for (; i < numChars; ++i, ++glyph_pos) {
                unsigned int uc = getChar(str, i, numChars);
                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
                if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
            }
        } else if (ttf) {
            for (; i < numChars; ++i, ++glyph_pos) {
                unsigned int uc = getChar(str, i, numChars);
                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
            }
        } else {
#endif
            wchar_t first = tm.tmFirstChar;
            wchar_t last = tm.tmLastChar;

            for (; i < numChars; ++i, ++glyph_pos) {
                uint uc = getChar(str, i, numChars);
                if (
#ifdef Q_WS_WINCE
                    tm.tmFirstChar > 60000 || // see comment in QFontEngineWin
#endif
                        uc >= first && uc <= last)
                    glyphs->glyphs[glyph_pos] = uc;
                else
                    glyphs->glyphs[glyph_pos] = 0;
            }
        }
    }
    glyphs->numGlyphs = glyph_pos;
    return glyph_pos;
}


QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont, LOGFONT lf)
{
    //qDebug("regular windows font engine created: font='%s', size=%d", name, lf.lfHeight);

    _name = name;

    cmap = 0;
    cmapSize = 0;
    hfont = _hfont;
    logfont = lf;
    HDC hdc = shared_dc();
    SelectObject(hdc, hfont);
    this->stockFont = stockFont;
    fontDef.pixelSize = -lf.lfHeight;

    lbearing = SHRT_MIN;
    rbearing = SHRT_MIN;
    synthesized_flags = -1;
    lineWidth = -1;
    x_height = -1;

    BOOL res = GetTextMetrics(hdc, &tm);
    fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
    if (!res) {
        qErrnoWarning("QFontEngineWin: GetTextMetrics failed");
        ZeroMemory(&tm, sizeof(TEXTMETRIC));
    }

    cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
    getCMap();

    widthCache = 0;
    widthCacheSize = 0;
    designAdvances = 0;
    designAdvancesSize = 0;

#ifndef Q_WS_WINCE
    if (!resolvedGetCharWidthI)
        resolveGetCharWidthI();
#endif
}
Example #3
0
BOOL WINAPI _export BLExtTextOut(HDC hDC,
                                 int x,
                                 int y,
                                 UINT fuOpt,
                                 const RECT FAR* lprc,
                                 LPCSTR lpStr,
                                 UINT cbLen,
                                 int FAR* lpDx)
{
	POINT pt ;
	HWND hWDC ;
	HWND hWPT ;
	
#ifdef _DEBUG
    DbgPrintf("NhWSrh.DLL     BLExtTextOut Begin");
    DbgPrintf("NhWSrh.DLL     BLExtTextOut hDC: %d, x: %d, y: %d, fuOpt: %d, cbLen: %d", 
        	  hDC,
        	  x,
        	  y,
        	  fuOpt,
        	  cbLen);
#endif
        // restore the old textout.
        RestoreWinApi(&g_ExtTextOutHook);
    
	//Added by XGL, Nov 3rd, 1998
	//We cannot get corret word with Explorer as background window
	//in Windows98, so this situation must be dealt with.
	pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y ;
	hWDC = WindowFromDC(hDC) ;
	hWPT = WindowFromPoint(pt) ;

	if (hWDC == NULL || hWPT == hWDC
		|| IsParentOrSelf(hWPT, hWDC)
		|| IsParentOrSelf(hWDC, hWPT))
	{
	//Adding ends. XGL, Nov 3rd, 1998

		if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpStr, cbLen)) && (cbLen > 0))
        {
                g_nTextAlign = GetTextAlign(hDC);
                g_nExtra     = GetTextCharacterExtra(hDC);
                GetCurrentPositionEx(hDC, &g_CurPos);
                GetTextMetrics(hDC, &g_tm);
///////////////////////////////////////////////////////////////////////////
// Modify by Yan/Gang 1997/11/18
// 用於修改在计算 TA_CENTER 情况的失误。
	g_dwDCOrg = 0;
		bRecAllRect = FALSE;
		GetStringRect(hDC, (LPSTR)lpStr, cbLen, x, y, &g_rcTotalRect, lpDx);
		bRecAllRect = TRUE;
// End Modify
///////////////////////////////////////////////////////////////////////////

                if ((WindowFromDC != NULL)&&(WindowFromDC(hDC) == NULL))
                {
#ifdef _DEBUG
                        DbgPrintf("NhWSrh.DLL     BLTextOut WindowFromDC() == NULL");
                        DbgLPCSTR("NhWSrh.DLL     BLTextOut: ", (LPSTR)lpStr, cbLen, TRUE);
#endif
                        // 赋零,用於避免MEMDC对串位置的影响·
                        g_dwDCOrg = 0;
                        
                        AddToTextOutBuffer(hDC, (LPSTR)lpStr, cbLen, x, y, lpDx);
                }
                else
                {
#ifdef _DEBUG
                        DbgPrintf("NhWSrh.DLL     BLTextOut WindowFromDC() != NULL");
                        DbgLPCSTR("NhWSrh.DLL     BLTextOut: ", (LPSTR)lpStr, cbLen, TRUE);
#endif
                        g_dwDCOrg    = GetDCOrg(hDC);
        
                        GetCurMousePosWord(hDC, (LPSTR)lpStr, cbLen, x, y, lpDx);
                }
		}
		else
		{
#ifdef _DEBUG
			DbgPrintf("NhWSrh.DLL     BLExtTextOut ((!g_bAllowGetCurWord) || (IsBadReadPtr(lpStr, cbLen)) && (cbLen <= 0))");
			if (!g_bAllowGetCurWord)
			{
				DbgPrintf("NhWSrh.DLL     BLExtTextOut !g_bAllowGetCurWord");
			}
			if (IsBadReadPtr(lpStr, cbLen))
			{
				DbgPrintf("NhWSrh.DLL     BLExtTextOut IsBadReadPtr()");
			}
			if (cbLen <= 0)
			{
				DbgPrintf("NhWSrh.DLL     BLExtTextOut cbLen <= 0");
			}
#endif
		}
    }
        // call old textout.
        ExtTextOut(hDC, x, y, fuOpt, lprc, lpStr, cbLen, lpDx);
        HookWinApi(&g_ExtTextOutHook, ONLYHOOK);
#ifdef _DEBUG
        DbgPrintf("NhWSrh.DLL     BLExtTextOut End");
#endif
        return (TRUE);
}         
Example #4
0
    void Update()
    {
        if(m_text==m_ss.str()){
            return;
        }

        m_text=m_ss.str();

        m_image->Clear();
        BYTE *data=m_image->GetSample();
        int pitch=m_image->GetWidth()*4;

        // フォントの生成
        LOGFONT lf = {m_fontsize, 0, 0, 0, 0, 0, 0, 0, 
            SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
            CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_MODERN, _T("MS 明朝")};
        HFONT hFont=CreateFontIndirect(&lf);
        if(!(hFont)){
            return;
        }

        // デバイスコンテキスト取得
        // デバイスにフォントを持たせないとGetGlyphOutline関数はエラーとなる
        HDC hdc = GetDC(NULL);
        HFONT oldFont = (HFONT)SelectObject(hdc, hFont);

        std::vector<BYTE> gryph;
        int x_pos=0;
        int y_pos=0;
        int col_size=m_fontsize/2;
        for(auto c=m_text.begin(); c!=m_text.end(); ++c){

            if(y_pos>=m_row*m_fontsize){
                break;
            }

            if(*c==L'\n'){
                y_pos+=m_fontsize+5;
                x_pos=0;
                continue;
            }

            if(x_pos+col_size>=m_col*col_size){
                y_pos+=m_fontsize+5;
                x_pos=0;
            }

            // フォントビットマップ取得
            TEXTMETRIC TM;
            GetTextMetrics( hdc, &TM );
            GLYPHMETRICS GM;
            CONST MAT2 Mat = {{0,1},{0,0},{0,0},{0,1}};
            DWORD size = GetGlyphOutline(hdc, *c, GGO_GRAY4_BITMAP, &GM, 0, NULL, &Mat);

            if(size>0){
                gryph.resize(size);
                GetGlyphOutline(hdc, *c, GGO_GRAY4_BITMAP, &GM, gryph.size(), &gryph[0], &Mat);

                // フォント情報の書き込み
                // iOfs_x, iOfs_y : 書き出し位置(左上)
                // iBmp_w, iBmp_h : フォントビットマップの幅高
                // Level : α値の段階 (GGO_GRAY4_BITMAPなので17段階)
                int iOfs_x = x_pos+GM.gmptGlyphOrigin.x;
                int iOfs_y = y_pos+TM.tmAscent - GM.gmptGlyphOrigin.y;
                int iBmp_w = GM.gmBlackBoxX + (4-(GM.gmBlackBoxX%4))%4;
                int iBmp_h = GM.gmBlackBoxY;
                int Level = 17;
                DWORD Alpha, Color;
                for(int y=iOfs_y; y<iOfs_y+iBmp_h; y++){
                    for(size_t x=iOfs_x; x<iOfs_x+GM.gmBlackBoxX; x++){
                        Alpha = (255 * gryph[x-iOfs_x + iBmp_w*(y-iOfs_y)]) / (Level-1);
                        Color = 0x00ffffff | (Alpha<<24);
                        memcpy((BYTE*)data + pitch*y + 4*x, &Color, sizeof(DWORD));
                    }
                }
                x_pos+=iBmp_w;
            }
            else{
                x_pos+=col_size;
            }
        }

        // デバイスコンテキストとフォントハンドルの開放
        SelectObject(hdc, oldFont);
        DeleteObject(hFont);
        ReleaseDC(NULL, hdc);
    }
Example #5
0
extern "C" BOOL EditPrint(HWND hwnd,LPCWSTR pszDocTitle,LPCWSTR pszPageFormat)
{

  // Don't print empty documents
  if (SendMessage(hwnd,SCI_GETLENGTH,0,0) == 0) {
    MsgBox(MBWARN,IDS_PRINT_EMPTY);
    return TRUE;
  }

  int startPos;
  int endPos;

  HDC hdc;

  RECT rectMargins;
  RECT rectPhysMargins;
  RECT rectSetup;
  POINT ptPage;
  POINT ptDpi;

  //RECT rectSetup;

  TEXTMETRIC tm;

  int headerLineHeight;
  HFONT fontHeader;

  int footerLineHeight;
  HFONT fontFooter;

  WCHAR dateString[256];

  DOCINFO di = {sizeof(DOCINFO), 0, 0, 0, 0};

  LONG lengthDoc;
  LONG lengthDocMax;
  LONG lengthPrinted;

  struct RangeToFormat frPrint;

  int pageNum;
  BOOL printPage;

  WCHAR pageString[32];

  HPEN pen;
  HPEN penOld;

  PRINTDLG pdlg = { sizeof(PRINTDLG), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  pdlg.hwndOwner = GetParent(hwnd);
  pdlg.hInstance = g_hInstance;
  pdlg.Flags = PD_USEDEVMODECOPIES | PD_ALLPAGES | PD_RETURNDC;
  pdlg.nFromPage = 1;
  pdlg.nToPage = 1;
  pdlg.nMinPage = 1;
  pdlg.nMaxPage = 0xffffU;
  pdlg.nCopies = 1;
  pdlg.hDC = 0;
  pdlg.hDevMode = hDevMode;
  pdlg.hDevNames = hDevNames;

  startPos = SendMessage(hwnd,SCI_GETSELECTIONSTART,0,0);;
  endPos = SendMessage(hwnd,SCI_GETSELECTIONEND,0,0);

  if (startPos == endPos) {
    pdlg.Flags |= PD_NOSELECTION;
  } else {
    pdlg.Flags |= PD_SELECTION;
  }
  if (0) {
    // Don't display dialog box, just use the default printer and options
    pdlg.Flags |= PD_RETURNDEFAULT;
  }
  if (!PrintDlg(&pdlg)) {
    return TRUE; // False means error...
  }

  hDevMode = pdlg.hDevMode;
  hDevNames = pdlg.hDevNames;

  hdc = pdlg.hDC;

  // Get printer resolution
  ptDpi.x = GetDeviceCaps(hdc, LOGPIXELSX);    // dpi in X direction
  ptDpi.y = GetDeviceCaps(hdc, LOGPIXELSY);    // dpi in Y direction

  // Start by getting the physical page size (in device units).
  ptPage.x = GetDeviceCaps(hdc, PHYSICALWIDTH);   // device units
  ptPage.y = GetDeviceCaps(hdc, PHYSICALHEIGHT);  // device units

  // Get the dimensions of the unprintable
  // part of the page (in device units).
  rectPhysMargins.left = GetDeviceCaps(hdc, PHYSICALOFFSETX);
  rectPhysMargins.top = GetDeviceCaps(hdc, PHYSICALOFFSETY);

  // To get the right and lower unprintable area,
  // we take the entire width and height of the paper and
  // subtract everything else.
  rectPhysMargins.right = ptPage.x            // total paper width
                          - GetDeviceCaps(hdc, HORZRES) // printable width
                          - rectPhysMargins.left;        // left unprintable margin

  rectPhysMargins.bottom = ptPage.y            // total paper height
                           - GetDeviceCaps(hdc, VERTRES)  // printable height
                           - rectPhysMargins.top;        // right unprintable margin

  // At this point, rectPhysMargins contains the widths of the
  // unprintable regions on all four sides of the page in device units.

  // Take in account the page setup given by the user (if one value is not null)
  if (pagesetupMargin.left != 0 || pagesetupMargin.right != 0 ||
          pagesetupMargin.top != 0 || pagesetupMargin.bottom != 0) {

    // Convert the hundredths of millimeters (HiMetric) or
    // thousandths of inches (HiEnglish) margin values
    // from the Page Setup dialog to device units.
    // (There are 2540 hundredths of a mm in an inch.)

    WCHAR localeInfo[3];
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3);

    if (localeInfo[0] == L'0') {  // Metric system. L'1' is US System
      rectSetup.left = MulDiv (pagesetupMargin.left, ptDpi.x, 2540);
      rectSetup.top = MulDiv (pagesetupMargin.top, ptDpi.y, 2540);
      rectSetup.right  = MulDiv(pagesetupMargin.right, ptDpi.x, 2540);
      rectSetup.bottom  = MulDiv(pagesetupMargin.bottom, ptDpi.y, 2540);
    } else {
      rectSetup.left  = MulDiv(pagesetupMargin.left, ptDpi.x, 1000);
      rectSetup.top  = MulDiv(pagesetupMargin.top, ptDpi.y, 1000);
      rectSetup.right  = MulDiv(pagesetupMargin.right, ptDpi.x, 1000);
      rectSetup.bottom  = MulDiv(pagesetupMargin.bottom, ptDpi.y, 1000);
    }

    // Dont reduce margins below the minimum printable area
    rectMargins.left  = max(rectPhysMargins.left, rectSetup.left);
    rectMargins.top  = max(rectPhysMargins.top, rectSetup.top);
    rectMargins.right  = max(rectPhysMargins.right, rectSetup.right);
    rectMargins.bottom  = max(rectPhysMargins.bottom, rectSetup.bottom);
  } else {
    rectMargins.left  = rectPhysMargins.left;
    rectMargins.top  = rectPhysMargins.top;
    rectMargins.right  = rectPhysMargins.right;
    rectMargins.bottom  = rectPhysMargins.bottom;
  }

  // rectMargins now contains the values used to shrink the printable
  // area of the page.

  // Convert device coordinates into logical coordinates
  DPtoLP(hdc, (LPPOINT)&rectMargins, 2);
  DPtoLP(hdc, (LPPOINT)&rectPhysMargins, 2);

  // Convert page size to logical units and we're done!
  DPtoLP(hdc, (LPPOINT) &ptPage, 1);

  headerLineHeight = MulDiv(8,ptDpi.y, 72);
  fontHeader = CreateFont(headerLineHeight,
                          0, 0, 0,
                          FW_BOLD,
                          0,
                          0,
                          0, 0, 0,
                          0, 0, 0,
                          L"Arial");
  SelectObject(hdc, fontHeader);
  GetTextMetrics(hdc, &tm);
  headerLineHeight = tm.tmHeight + tm.tmExternalLeading;

  if (iPrintHeader == 3)
    headerLineHeight = 0;

  footerLineHeight = MulDiv(7,ptDpi.y, 72);
  fontFooter = CreateFont(footerLineHeight,
                          0, 0, 0,
                          FW_NORMAL,
                          0,
                          0,
                          0, 0, 0,
                          0, 0, 0,
                          L"Arial");
  SelectObject(hdc, fontFooter);
  GetTextMetrics(hdc, &tm);
  footerLineHeight = tm.tmHeight + tm.tmExternalLeading;

  if (iPrintFooter == 1)
    footerLineHeight = 0;

  di.lpszDocName = pszDocTitle;
  di.lpszOutput = 0;
  di.lpszDatatype = 0;
  di.fwType = 0;
  if (StartDoc(hdc, &di) < 0) {
    DeleteDC(hdc);
    if (fontHeader)
      DeleteObject(fontHeader);
    if (fontFooter)
      DeleteObject(fontFooter);
    return FALSE;
  }

  // Get current date...
  SYSTEMTIME st;
  GetLocalTime(&st);
  GetDateFormat(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,dateString,256);

  // Get current time...
  if (iPrintHeader == 0)
  {
    WCHAR timeString[128];
    GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOSECONDS,&st,NULL,timeString,128);
    lstrcat(dateString,L" ");
    lstrcat(dateString,timeString);
  }

  // Set print color mode
  int printColorModes[5] = {
    SC_PRINT_NORMAL,
    SC_PRINT_INVERTLIGHT,
    SC_PRINT_BLACKONWHITE,
    SC_PRINT_COLOURONWHITE,
    SC_PRINT_COLOURONWHITEDEFAULTBG };
  SendMessage(hwnd,SCI_SETPRINTCOLOURMODE,printColorModes[iPrintColor],0);

  // Set print zoom...
  SendMessage(hwnd,SCI_SETPRINTMAGNIFICATION,(WPARAM)iPrintZoom,0);

  lengthDoc = SendMessage(hwnd,SCI_GETLENGTH,0,0);
  lengthDocMax = lengthDoc;
  lengthPrinted = 0;

  // Requested to print selection
  if (pdlg.Flags & PD_SELECTION) {
    if (startPos > endPos) {
      lengthPrinted = endPos;
      lengthDoc = startPos;
    } else {
      lengthPrinted = startPos;
      lengthDoc = endPos;
    }

    if (lengthPrinted < 0)
      lengthPrinted = 0;
    if (lengthDoc > lengthDocMax)
      lengthDoc = lengthDocMax;
  }

  // We must substract the physical margins from the printable area
  frPrint.hdc = hdc;
  frPrint.hdcTarget = hdc;
  frPrint.rc.left = rectMargins.left - rectPhysMargins.left;
  frPrint.rc.top = rectMargins.top - rectPhysMargins.top;
  frPrint.rc.right = ptPage.x - rectMargins.right - rectPhysMargins.left;
  frPrint.rc.bottom = ptPage.y - rectMargins.bottom - rectPhysMargins.top;
  frPrint.rcPage.left = 0;
  frPrint.rcPage.top = 0;
  frPrint.rcPage.right = ptPage.x - rectPhysMargins.left - rectPhysMargins.right - 1;
  frPrint.rcPage.bottom = ptPage.y - rectPhysMargins.top - rectPhysMargins.bottom - 1;
  frPrint.rc.top += headerLineHeight + headerLineHeight / 2;
  frPrint.rc.bottom -= footerLineHeight + footerLineHeight / 2;
  // Print each page
  pageNum = 1;

  while (lengthPrinted < lengthDoc) {
    printPage = (!(pdlg.Flags & PD_PAGENUMS) ||
                 (pageNum >= pdlg.nFromPage) && (pageNum <= pdlg.nToPage));

    wsprintf(pageString, pszPageFormat, pageNum);

    if (printPage) {

      // Show wait cursor...
      BeginWaitCursor();

      // Display current page number in Statusbar
      StatusUpdatePrintPage(pageNum);

      StartPage(hdc);

      SetTextColor(hdc, RGB(0,0,0));
      SetBkColor(hdc, RGB(255,255,255));
      SelectObject(hdc, fontHeader);
      UINT ta = SetTextAlign(hdc, TA_BOTTOM);
      RECT rcw = {frPrint.rc.left, frPrint.rc.top - headerLineHeight - headerLineHeight / 2,
                  frPrint.rc.right, frPrint.rc.top - headerLineHeight / 2};
      rcw.bottom = rcw.top + headerLineHeight;

      if (iPrintHeader < 3)
      {
        ExtTextOut(hdc, frPrint.rc.left + 5, frPrint.rc.top - headerLineHeight / 2,
                      /*ETO_OPAQUE*/0, &rcw, pszDocTitle,
                      lstrlen(pszDocTitle), NULL);
      }

      // Print date in header
      if (iPrintHeader == 0 || iPrintHeader == 1)
      {
        SIZE sizeInfo;
        SelectObject(hdc,fontFooter);
        GetTextExtentPoint32(hdc,dateString,lstrlen(dateString),&sizeInfo);
        ExtTextOut(hdc, frPrint.rc.right - 5 - sizeInfo.cx, frPrint.rc.top - headerLineHeight / 2,
                      /*ETO_OPAQUE*/0, &rcw, dateString,
                      lstrlen(dateString), NULL);
      }

      if (iPrintHeader < 3)
      {
        SetTextAlign(hdc, ta);
        pen = CreatePen(0, 1, RGB(0,0,0));
        penOld = (HPEN)SelectObject(hdc, pen);
        MoveToEx(hdc, frPrint.rc.left, frPrint.rc.top - headerLineHeight / 4, NULL);
        LineTo(hdc, frPrint.rc.right, frPrint.rc.top - headerLineHeight / 4);
        SelectObject(hdc, penOld);
        DeleteObject(pen);
      }
    }

    frPrint.chrg.cpMin = lengthPrinted;
    frPrint.chrg.cpMax = lengthDoc;

    lengthPrinted = SendMessage(hwnd,SCI_FORMATRANGE,printPage,(LPARAM)&frPrint);

    if (printPage) {
      SetTextColor(hdc, RGB(0,0,0));
      SetBkColor(hdc, RGB(255,255,255));
      SelectObject(hdc, fontFooter);
      UINT ta = SetTextAlign(hdc, TA_TOP);
      RECT rcw = {frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 2,
                  frPrint.rc.right, frPrint.rc.bottom + footerLineHeight + footerLineHeight / 2};

      if (iPrintFooter == 0)
      {
        SIZE sizeFooter;
        GetTextExtentPoint32(hdc,pageString,lstrlen(pageString),&sizeFooter);
        ExtTextOut(hdc, frPrint.rc.right - 5 - sizeFooter.cx, frPrint.rc.bottom + footerLineHeight / 2,
                      /*ETO_OPAQUE*/0, &rcw, pageString,
                      lstrlen(pageString), NULL);

        SetTextAlign(hdc, ta);
        pen = ::CreatePen(0, 1, RGB(0,0,0));
        penOld = (HPEN)SelectObject(hdc, pen);
        SetBkColor(hdc, RGB(0,0,0));
        MoveToEx(hdc, frPrint.rc.left, frPrint.rc.bottom + footerLineHeight / 4, NULL);
        LineTo(hdc, frPrint.rc.right, frPrint.rc.bottom + footerLineHeight / 4);
        SelectObject(hdc, penOld);
        DeleteObject(pen);
      }

      EndPage(hdc);
    }
    pageNum++;

    if ((pdlg.Flags & PD_PAGENUMS) && (pageNum > pdlg.nToPage))
      break;
  }

  SendMessage(hwnd,SCI_FORMATRANGE, FALSE, 0);

  EndDoc(hdc);
  DeleteDC(hdc);
  if (fontHeader)
    DeleteObject(fontHeader);
  if (fontFooter)
    DeleteObject(fontFooter);

  // Reset Statusbar to default mode
  StatusSetSimple(hwndStatus,FALSE);

  // Remove wait cursor...
  EndWaitCursor();

  return TRUE;
}
Example #6
0
int Wout::GetTextName()
{
	GetTextMetrics(hDC, &textInfo);
	return textInfo.
}
Example #7
0
JNIEXPORT jlong JNICALL
Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
(JNIEnv *env, jobject unused,
 jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) {

    GLYPHMETRICS glyphMetrics;
    LOGFONTW lf;
    BITMAPINFO bmi;
    TEXTMETRIC textMetric;
    RECT rect;
    int bytesWidth, dibBytesWidth, extra, imageSize, dibImageSize;
    unsigned char* dibImage = NULL, *rowPtr, *pixelPtr, *dibPixPtr, *dibRowPtr;
    unsigned char r,g,b;
    unsigned char* igTable;
    GlyphInfo* glyphInfo = NULL;
    int nameLen;
    LPWSTR name;
    HFONT oldFont, hFont;
    MAT2 mat2;

    unsigned short width;
    unsigned short height;
    short advanceX;
    short advanceY;
    int topLeftX;
    int topLeftY;
    int err;
    int bmWidth, bmHeight;
    int x, y;
    HBITMAP hBitmap = NULL, hOrigBM;
    int gamma, orient;

    HWND hWnd = NULL;
    HDC hDesktopDC = NULL;
    HDC hMemoryDC = NULL;

    hWnd = GetDesktopWindow();
    hDesktopDC = GetWindowDC(hWnd);
    if (hDesktopDC == NULL) {
        return (jlong)0;
    }
    if (GetDeviceCaps(hDesktopDC, BITSPIXEL) < 15) {
        FREE_AND_RETURN;
    }

    hMemoryDC = CreateCompatibleDC(hDesktopDC);
    if (hMemoryDC == NULL || fontFamily == NULL) {
        FREE_AND_RETURN;
    }
    err = SetMapMode(hMemoryDC, MM_TEXT);
    if (err == 0) {
        FREE_AND_RETURN;
    }

    memset(&lf, 0, sizeof(LOGFONTW));
    lf.lfHeight = -size;
    lf.lfWeight = (style & 1) ? FW_BOLD : FW_NORMAL;
    lf.lfItalic = (style & 2) ? 0xff : 0;
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfQuality = CLEARTYPE_QUALITY;
    lf.lfOutPrecision = OUT_TT_PRECIS;
    lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lf.lfPitchAndFamily = DEFAULT_PITCH;

    nameLen = (*env)->GetStringLength(env, fontFamily);
    name = (LPWSTR)alloca((nameLen+1)*2);
    if (name == NULL) {
       FREE_AND_RETURN;
    }
    (*env)->GetStringRegion(env, fontFamily, 0, nameLen, name);
    name[nameLen] = '\0';

    if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
        wcscpy(lf.lfFaceName, name);
    } else {
        FREE_AND_RETURN;
    }

    hFont = CreateFontIndirectW(&lf);
    if (hFont == NULL) {
        FREE_AND_RETURN;
    }
    oldFont = SelectObject(hMemoryDC, hFont);

    memset(&textMetric, 0, sizeof(TEXTMETRIC));
    err = GetTextMetrics(hMemoryDC, &textMetric);
    if (err == 0) {
        FREE_AND_RETURN;
    }
    memset(&glyphMetrics, 0, sizeof(GLYPHMETRICS));
    memset(&mat2, 0, sizeof(MAT2));
    mat2.eM11.value = 1; mat2.eM22.value = 1;
    err = GetGlyphOutline(hMemoryDC, glyphCode,
                          GGO_METRICS|GGO_GLYPH_INDEX,
                          &glyphMetrics,
                          0, NULL, &mat2);
    if (err == GDI_ERROR) {
        /* Probably no such glyph - ie the font wasn't the one we expected. */
        FREE_AND_RETURN;
    }

    width  = (unsigned short)glyphMetrics.gmBlackBoxX;
    height = (unsigned short)glyphMetrics.gmBlackBoxY;

    /* Don't handle "invisible" glyphs in this code */
    if (width <= 0 || height == 0) {
       FREE_AND_RETURN;
    }

    advanceX = glyphMetrics.gmCellIncX;
    advanceY = glyphMetrics.gmCellIncY;
    topLeftX = glyphMetrics.gmptGlyphOrigin.x;
    topLeftY = glyphMetrics.gmptGlyphOrigin.y;

    /* GetGlyphOutline pre-dates cleartype and I'm not sure that it will
     * account for all pixels touched by the rendering. Need to widen,
     * and also adjust by one the x position at which it is rendered.
     * The extra pixels of width are used as follows :
     * One extra pixel at the left and the right will be needed to absorb
     * the pixels that will be touched by filtering by GDI to compensate
     * for colour fringing.
     * However there seem to be some cases where GDI renders two extra
     * pixels to the right, so we add one additional pixel to the right,
     * and in the code that copies this to the image cache we test for
     * the (rare) cases when this is touched, and if its not reduce the
     * stated image width for the blitting loops.
     * For fractional metrics :
     * One extra pixel at each end to account for sub-pixel positioning used
     * when fractional metrics is on in LCD mode.
     * The pixel at the left is needed so the blitting loop can index into
     * that a byte at a time to more accurately position the glyph.
     * The pixel at the right is needed so that when such indexing happens,
     * the blitting still can use the same width.
     * Consequently the width that is specified for the glyph is one less
     * than that of the actual image.
     * Note that in the FM case as a consequence we need to adjust the
     * position at which GDI renders, and the declared width of the glyph
     * See the if (fm) {} cases in the code.
     * For the non-FM case, we not only save 3 bytes per row, but this
     * prevents apparent glyph overlapping which affects the rendering
     * performance of accelerated pipelines since it adds additional
     * read-back requirements.
     */
    width+=3;
    if (fm) {
        width+=1;
    }
    /* DIB scanline must end on a DWORD boundary. We specify 3 bytes per pixel,
     * so must round up as needed to a multiple of 4 bytes.
     */
    dibBytesWidth = bytesWidth = width*3;
    extra = dibBytesWidth % 4;
    if (extra != 0) {
        dibBytesWidth += (4-extra);
    }
    /* The glyph cache image must be a multiple of 3 bytes wide. */
    extra = bytesWidth % 3;
    if (extra != 0) {
        bytesWidth += (3-extra);
    }
    bmWidth = width;
    bmHeight = height;

    /* Must use desktop DC to create a bitmap of that depth */
    hBitmap = CreateCompatibleBitmap(hDesktopDC, bmWidth, bmHeight);
    if (hBitmap == NULL) {
        FREE_AND_RETURN;
    }
    hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    /* Fill in black */
    rect.left = 0;
    rect.top = 0;
    rect.right = bmWidth;
    rect.bottom = bmHeight;
    FillRect(hMemoryDC, (LPRECT)&rect, GetStockObject(BLACK_BRUSH));

    /* Set text color to white, background to black. */
    SetBkColor(hMemoryDC, RGB(0,0,0));
    SetTextColor(hMemoryDC, RGB(255,255,255));

    /* adjust rendering position */
    x = -topLeftX+1;
    if (fm) {
        x += 1;
    }
    y = topLeftY - textMetric.tmAscent;
    err = ExtTextOutW(hMemoryDC, x, y, ETO_GLYPH_INDEX|ETO_OPAQUE,
                (LPRECT)&rect, (LPCWSTR)&glyphCode, 1, NULL);
    if (err == 0) {
        FREE_AND_RETURN;
    }

    /* Now get the image into a DIB.
     * MS docs for GetDIBits says the compatible bitmap must not be
     * selected into a DC, so restore the original first.
     */
    SelectObject(hMemoryDC, hOrigBM);
    SelectObject(hMemoryDC, oldFont);
    DeleteObject(hFont);

    memset(&bmi, 0, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;

    dibImageSize = dibBytesWidth*height;
    dibImage = malloc(dibImageSize);
    if (dibImage == NULL) {
        FREE_AND_RETURN;
    }
    memset(dibImage, 0, dibImageSize);

    err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage,
                    &bmi, DIB_RGB_COLORS);

    if (err == 0) {        /* GetDIBits failed. */
        FREE_AND_RETURN;
    }

    err = SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &orient, 0);
    if (err == 0) {
        FREE_AND_RETURN;
    }
    err = SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &gamma, 0);
    if (err == 0) {
        FREE_AND_RETURN;
    }
    igTable = getIGTable(gamma/10);
    if (igTable == NULL) {
        FREE_AND_RETURN;
    }

    /* Now copy glyph image into a GlyphInfo structure and return it.
     * NB the xadvance calculated here may be overwritten by the caller.
     * 1 is subtracted from the bitmap width to get the glyph width, since
     * that extra "1" was added as padding, so the sub-pixel positioning of
     * fractional metrics could index into it.
     */
    imageSize = bytesWidth*height;
    glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize);
    if (glyphInfo == NULL) {
        FREE_AND_RETURN;
    }
    glyphInfo->cellInfo = NULL;
    glyphInfo->rowBytes = bytesWidth;
    glyphInfo->width = width;
    if (fm) {
        glyphInfo->width -= 1; // must subtract 1
    }
    glyphInfo->height = height;
    glyphInfo->advanceX = advanceX;
    glyphInfo->advanceY = advanceY;
    glyphInfo->topLeftX = (float)(topLeftX-1);
    if (fm) {
        glyphInfo->topLeftX -= 1;
    }
    glyphInfo->topLeftY = (float)-topLeftY;
    glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo);
    memset(glyphInfo->image, 0, imageSize);

    /* DIB 24bpp data is always stored in BGR order, but we usually
     * need this in RGB, so we can't just memcpy and need to swap B and R.
     * Also need to apply inverse gamma adjustment here.
     * We re-use the variable "extra" to see if the last pixel is touched
     * at all. If its not we can reduce the glyph image width. This comes
     * into play in some cases where GDI touches more pixels than accounted
     * for by increasing width by two pixels over the B&W image. Whilst
     * the bytes are in the cache, it doesn't affect rendering performance
     * of the hardware pipelines.
     */
    extra = 0;
    if (fm) {
        extra = 1; // always need it.
    }
    dibRowPtr = dibImage;
    rowPtr = glyphInfo->image;
    for (y=0;y<height;y++) {
        pixelPtr = rowPtr;
        dibPixPtr = dibRowPtr;
        for (x=0;x<width;x++) {
            if (orient == FE_FONTSMOOTHINGORIENTATIONRGB) {
                b = *dibPixPtr++;
                g = *dibPixPtr++;
                r = *dibPixPtr++;
            } else {
                r = *dibPixPtr++;
                g = *dibPixPtr++;
                b = *dibPixPtr++;
            }
            *pixelPtr++ = igTable[r];
            *pixelPtr++ = igTable[g];
            *pixelPtr++ = igTable[b];
            if (!fm && (x==(width-1)) && (r|g|b)) {
                extra = 1;
            }
        }
        dibRowPtr += dibBytesWidth;
        rowPtr  += bytesWidth;
    }
    if (!extra) {
        glyphInfo->width -= 1;
    }

    free(dibImage);
    ReleaseDC(hWnd, hDesktopDC);
    DeleteObject(hMemoryDC);
    DeleteObject(hBitmap);

    return ptr_to_jlong(glyphInfo);
}
Example #8
0
static void InitChangeRegisterDialog(HWND hwnd,LPARAM lparam)
{
    RegModifyData   *data;
    char            *name;
    unsigned        len;
    mad_radix       radix;
    mad_type_info   mti;
    mad_type_info   cmp;
    char            s[255];
    RECT            p_rect;
    RECT            c_rect;
    HWND            field;
    int             i;
    unsigned        max_len;
    HDC             dc;
    TEXTMETRIC      tm;
    HWND            cancel;

    SetWindowLong( hwnd, DWL_USER, (LONG)lparam);
    data = (RegModifyData *)lparam;
    len = MADRegFullName( data->curr_info, ".", NULL, 0 );
    if( len > 0 ) {
        name = alloca( ( len + 1 ) * sizeof( char ) );
        MADRegFullName( data->curr_info, ".", name, len );
        SetWindowText( hwnd, name );
    } else {
        SetWindowText( hwnd, "" );
    }

    if( data->num_possible == 1 ) {
        field = GetDlgItem( hwnd, REG_EDIT_FIELD );
    } else {
        field = GetDlgItem( hwnd, CH_REG_COMBO_LIST );
    }
    SetMonoFont( field );
    GetChildPos( hwnd, field, &c_rect);
    dc = GetDC( field );
    GetTextMetrics( dc, &tm );
    MADTypeInfo( data->th, &mti );
    radix = MADTypePreferredRadix( data->th );

    if( data->num_possible == 1 ) {
        if( data->maxv == 0 ) {
            len = 255;
        } else {
            len = data->maxv;
        }
        MADTypeToString( radix, &mti, data->curr_value, s, &len );
        if( data->maxv == 0 ) {
            max_len = strlen( s );
        } else {
            max_len = data->maxv;
        }
        SetDlgItemText(hwnd,REG_EDIT_FIELD,s);
    } else {
        MADTypeInfo( data->curr_info->type, &cmp );
        max_len = 0;
        for( i = 0; i < data->num_possible; i++ ) {
            if( data->m_list[i].name == MAD_MSTR_NIL ) {
                len = sizeof( s );
                MADTypeToString( radix, &mti, data->m_list[i].data, s, &len );
            } else {
                MADCli( String )( data->m_list[i].name, s, sizeof( s ) );
            }
            if( max_len < strlen( s ) )
                max_len = strlen( s );
            SendDlgItemMessage( hwnd, CH_REG_COMBO_LIST, CB_ADDSTRING, 0, (LPARAM)s );
            if( memcmp( data->curr_value, data->m_list[i].data, BITS2BYTES( cmp.b.bits ) ) == 0 ) {
                SendDlgItemMessage( hwnd, CH_REG_COMBO_LIST, CB_SETCURSEL, (WPARAM)i, 0 );
            }
        }
        c_rect.bottom += SendMessage( field, CB_GETITEMHEIGHT, 0, 0 ) * (i + 1);
    }
    max_len *= tm.tmMaxCharWidth;
    if( max_len > c_rect.right ) {
        max_len -= max_len%2;
        GetWindowRect( hwnd, &p_rect );
        p_rect.right -= p_rect.left;
        p_rect.bottom -= p_rect.top;
        p_rect.left -= ( max_len - c_rect.right )/2;
        p_rect.right += ( max_len - c_rect.right );
        MoveWindow( hwnd, p_rect.left, p_rect.top, p_rect.right, p_rect.bottom, FALSE );
        cancel = GetDlgItem( hwnd, IDCANCEL );
        GetChildPos( hwnd, cancel, &p_rect );
        p_rect.left += ( max_len - c_rect.right );
        MoveWindow( cancel, p_rect.left, p_rect.top, p_rect.right, p_rect.bottom, FALSE );
        c_rect.right = max_len;
    }
    ReleaseDC( field, dc );
    MoveWindow( field, c_rect.left, c_rect.top, c_rect.right, c_rect.bottom, FALSE );
}
Example #9
0
    int
gui_mch_dialog(
    int		 type,
    char_u	*title,
    char_u	*message,
    char_u	*buttons,
    int		 dfltbutton,
    char_u	*textfield,
    int		ex_cmd)
{
    FARPROC	dp;
    LPWORD	p, pnumitems;
    int		numButtons;
    int		*buttonWidths, *buttonPositions;
    int		buttonYpos;
    int		nchar, i;
    DWORD	lStyle;
    int		dlgwidth = 0;
    int		dlgheight;
    int		editboxheight;
    int		horizWidth;
    int		msgheight;
    char_u	*pstart;
    char_u	*pend;
    char_u	*tbuffer;
    RECT	rect;
    HWND	hwnd;
    HDC		hdc;
    HFONT	oldFont;
    TEXTMETRIC	fontInfo;
    int		fontHeight;
    int		textWidth, minButtonWidth, messageWidth;
    int		maxDialogWidth;
    int		vertical;
    int		dlgPaddingX;
    int		dlgPaddingY;
    HGLOBAL	hglbDlgTemp;

#ifndef NO_CONSOLE
    /* Don't output anything in silent mode ("ex -s") */
    if (silent_mode)
	return dfltbutton;   /* return default option */
#endif

    /* If there is no window yet, open it. */
    if (s_hwnd == NULL && gui_mch_init() == FAIL)
	return dfltbutton;

    if ((type < 0) || (type > VIM_LAST_TYPE))
	type = 0;

    /* allocate some memory for dialog template */
    /* TODO should compute this really*/

    hglbDlgTemp = GlobalAlloc(GHND,  DLG_ALLOC_SIZE);
    if (hglbDlgTemp == NULL)
	return -1;

    p = (LPWORD) GlobalLock(hglbDlgTemp);

    if (p == NULL)
	return -1;

    /*
     * make a copy of 'buttons' to fiddle with it.  compiler grizzles because
     * vim_strsave() doesn't take a const arg (why not?), so cast away the
     * const.
     */
    tbuffer = vim_strsave(buttons);
    if (tbuffer == NULL)
	return -1;

    --dfltbutton;   /* Change from one-based to zero-based */

    /* Count buttons */
    numButtons = 1;
    for (i = 0; tbuffer[i] != '\0'; i++)
    {
	if (tbuffer[i] == DLG_BUTTON_SEP)
	    numButtons++;
    }
    if (dfltbutton >= numButtons)
	dfltbutton = 0;

    /* Allocate array to hold the width of each button */
    buttonWidths = (int *) lalloc(numButtons * sizeof(int), TRUE);
    if (buttonWidths == NULL)
	return -1;

    /* Allocate array to hold the X position of each button */
    buttonPositions = (int *) lalloc(numButtons * sizeof(int), TRUE);
    if (buttonPositions == NULL)
	return -1;

    /*
     * Calculate how big the dialog must be.
     */
    hwnd = GetDesktopWindow();
    hdc = GetWindowDC(hwnd);
    oldFont = SelectFont(hdc, GetStockObject(SYSTEM_FONT));
    dlgPaddingX = DLG_OLD_STYLE_PADDING_X;
    dlgPaddingY = DLG_OLD_STYLE_PADDING_Y;

    GetTextMetrics(hdc, &fontInfo);
    fontHeight = fontInfo.tmHeight;

    /* Minimum width for horizontal button */
    minButtonWidth = GetTextWidth(hdc, "Cancel", 6);

    /* Maximum width of a dialog, if possible */
    GetWindowRect(s_hwnd, &rect);
    maxDialogWidth = rect.right - rect.left
		     - GetSystemMetrics(SM_CXFRAME) * 2;
    if (maxDialogWidth < DLG_MIN_MAX_WIDTH)
	maxDialogWidth = DLG_MIN_MAX_WIDTH;

    /* Set dlgwidth to width of message */
    pstart = message;
    messageWidth = 0;
    msgheight = 0;
    do
    {
	pend = vim_strchr(pstart, DLG_BUTTON_SEP);
	if (pend == NULL)
	    pend = pstart + STRLEN(pstart);	/* Last line of message. */
	msgheight += fontHeight;
	textWidth = GetTextWidth(hdc, pstart, pend - pstart);
	if (textWidth > messageWidth)
	    messageWidth = textWidth;
	pstart = pend + 1;
    } while (*pend != NUL);
    dlgwidth = messageWidth;

    /* Add width of icon to dlgwidth, and some space */
    dlgwidth += DLG_ICON_WIDTH + 3 * dlgPaddingX;

    if (msgheight < DLG_ICON_HEIGHT)
	msgheight = DLG_ICON_HEIGHT;

    /*
     * Check button names.  A long one will make the dialog wider.
     */
	 vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
    if (!vertical)
    {
	// Place buttons horizontally if they fit.
	horizWidth = dlgPaddingX;
	pstart = tbuffer;
	i = 0;
	do
	{
	    pend = vim_strchr(pstart, DLG_BUTTON_SEP);
	    if (pend == NULL)
		pend = pstart + STRLEN(pstart);	// Last button name.
	    textWidth = GetTextWidth(hdc, pstart, pend - pstart);
	    if (textWidth < minButtonWidth)
		textWidth = minButtonWidth;
	    textWidth += dlgPaddingX;	    /* Padding within button */
	    buttonWidths[i] = textWidth;
	    buttonPositions[i++] = horizWidth;
	    horizWidth += textWidth + dlgPaddingX; /* Pad between buttons */
	    pstart = pend + 1;
	} while (*pend != NUL);

	if (horizWidth > maxDialogWidth)
	    vertical = TRUE;	// Too wide to fit on the screen.
	else if (horizWidth > dlgwidth)
	    dlgwidth = horizWidth;
    }

    if (vertical)
    {
	// Stack buttons vertically.
	pstart = tbuffer;
	do
	{
	    pend = vim_strchr(pstart, DLG_BUTTON_SEP);
	    if (pend == NULL)
		pend = pstart + STRLEN(pstart);	// Last button name.
	    textWidth = GetTextWidth(hdc, pstart, pend - pstart);
	    textWidth += dlgPaddingX;		/* Padding within button */
	    textWidth += DLG_VERT_PADDING_X * 2; /* Padding around button */
	    if (textWidth > dlgwidth)
		dlgwidth = textWidth;
	    pstart = pend + 1;
	} while (*pend != NUL);
    }

    if (dlgwidth < DLG_MIN_WIDTH)
	dlgwidth = DLG_MIN_WIDTH;	/* Don't allow a really thin dialog!*/

    /* start to fill in the dlgtemplate information.  addressing by WORDs */
    lStyle = DS_MODALFRAME | WS_CAPTION | WS_VISIBLE ;

    add_long(lStyle);
    pnumitems = p;	/*save where the number of items must be stored*/
    add_byte(0);	// NumberOfItems(will change later)
    add_word(10);	// x
    add_word(10);	// y
    add_word(PixelToDialogX(dlgwidth));

    // Dialog height.
    if (vertical)
	dlgheight = msgheight + 2 * dlgPaddingY +
			      DLG_VERT_PADDING_Y + 2 * fontHeight * numButtons;
    else
	dlgheight = msgheight + 3 * dlgPaddingY + 2 * fontHeight;

    // Dialog needs to be taller if contains an edit box.
    editboxheight = fontHeight + dlgPaddingY + 4 * DLG_VERT_PADDING_Y;
    if (textfield != NULL)
	dlgheight += editboxheight;

    add_word(PixelToDialogY(dlgheight));

    add_byte(0);	//menu
    add_byte(0);	//class

    /* copy the title of the dialog */
    add_string(title ? title : ("Vim"VIM_VERSION_MEDIUM));

    buttonYpos = msgheight + 2 * dlgPaddingY;

    if (textfield != NULL)
	buttonYpos += editboxheight;

    pstart = tbuffer; //dflt_text
    horizWidth = (dlgwidth - horizWidth) / 2;	/* Now it's X offset */
    for (i = 0; i < numButtons; i++)
    {
	/* get end of this button. */
	for (	pend = pstart;
		*pend && (*pend != DLG_BUTTON_SEP);
		pend++)
	    ;

	if (*pend)
	    *pend = '\0';

	/*
	 * NOTE:
	 * setting the BS_DEFPUSHBUTTON style doesn't work because Windows sets
	 * the focus to the first tab-able button and in so doing makes that
	 * the default!! Grrr.  Workaround: Make the default button the only
	 * one with WS_TABSTOP style. Means user can't tab between buttons, but
	 * he/she can use arrow keys.
	 *
	 * NOTE (Thore): Setting BS_DEFPUSHBUTTON works fine when it's the
	 * first one, so I changed the correct button to be this style. This
	 * is necessary because when an edit box is added, we need a button to
	 * be default.  The edit box will be the default control, and when the
	 * user presses enter from the edit box we want the default button to
	 * be pressed.
	 */
	if (vertical)
	{
	    p = add_dialog_element(p,
		    ((i == dfltbutton || dfltbutton < 0) && textfield != NULL
			    ?  BS_DEFPUSHBUTTON : BS_PUSHBUTTON) | WS_TABSTOP,
		    PixelToDialogX(DLG_VERT_PADDING_X),
		    PixelToDialogY(buttonYpos /* TBK */
				   + 2 * fontHeight * i),
		    PixelToDialogX(dlgwidth - 2 * DLG_VERT_PADDING_X),
		    (WORD)(PixelToDialogY(2 * fontHeight) - 1),
		    (WORD)(IDCANCEL + 1 + i), (BYTE)0x80, pstart);
	}
	else
	{
	    p = add_dialog_element(p,
		    ((i == dfltbutton || dfltbutton < 0) && textfield != NULL
			     ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON) | WS_TABSTOP,
		    PixelToDialogX(horizWidth + buttonPositions[i]),
		    PixelToDialogY(buttonYpos), /* TBK */
		    PixelToDialogX(buttonWidths[i]),
		    (WORD)(PixelToDialogY(2 * fontHeight) - 1),
		    (WORD)(IDCANCEL + 1 + i), (BYTE)0x80, pstart);
	}

	pstart = pend + 1;	/*next button*/

    }
    *pnumitems += numButtons;

    /* Vim icon */
    p = add_dialog_element(p, SS_ICON,
	    PixelToDialogX(dlgPaddingX),
	    PixelToDialogY(dlgPaddingY),
	    PixelToDialogX(DLG_ICON_WIDTH),
	    PixelToDialogY(DLG_ICON_HEIGHT),
	    DLG_NONBUTTON_CONTROL + 0, (BYTE)0x82,
	    &dlg_icons[type]);


    /* Dialog message */
    p = add_dialog_element(p, SS_LEFT,
	    PixelToDialogX(2 * dlgPaddingX + DLG_ICON_WIDTH),
	    PixelToDialogY(dlgPaddingY),
	    (WORD)(PixelToDialogX(messageWidth) + 1),
	    PixelToDialogY(msgheight),
	    DLG_NONBUTTON_CONTROL + 1, (BYTE)0x82, message);

    /* Edit box */
    if (textfield != NULL)
    {
	p = add_dialog_element(p, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP | WS_BORDER,
		PixelToDialogX(2 * dlgPaddingX),
		PixelToDialogY(2 * dlgPaddingY + msgheight),
		PixelToDialogX(dlgwidth - 4 * dlgPaddingX),
		PixelToDialogY(fontHeight + dlgPaddingY),
		DLG_NONBUTTON_CONTROL + 2, (BYTE)0x81, textfield);
	*pnumitems += 1;
    }

    *pnumitems += 2;

    SelectFont(hdc, oldFont);
    ReleaseDC(hwnd, hdc);
    dp = MakeProcInstance((FARPROC)dialog_callback, s_hinst);


    /* Let the dialog_callback() function know which button to make default
     * If we have an edit box, make that the default. We also need to tell
     * dialog_callback() if this dialog contains an edit box or not. We do
     * this by setting s_textfield if it does.
     */
    if (textfield != NULL)
    {
	dialog_default_button = DLG_NONBUTTON_CONTROL + 2;
	s_textfield = textfield;
    }
    else
    {
	dialog_default_button = IDCANCEL + 1 + dfltbutton;
	s_textfield = NULL;
    }

    /*show the dialog box modally and get a return value*/
    nchar = DialogBoxIndirect(
	    s_hinst,
	    (HGLOBAL) hglbDlgTemp,
	    s_hwnd,
	    (DLGPROC)dp);

    FreeProcInstance( dp );
    GlobalUnlock(hglbDlgTemp);
    GlobalFree(hglbDlgTemp);
    vim_free(tbuffer);
    vim_free(buttonWidths);
    vim_free(buttonPositions);


    return nchar;
}
Example #10
0
LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HWND view;
	HDC hdc;
	HBRUSH hbr;
	HGDIOBJ oldfont;
	RECT rect;
	int titlelen;
	SIZE size;
	LOGFONT lf;
	TEXTMETRIC tm;
	HINSTANCE inst = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
	DRAWITEMSTRUCT *drawitem;
	CHARFORMAT2W format;

	switch (msg)
	{
	case WM_CREATE:
		// Create game title static control
		memset (&lf, 0, sizeof(lf));
		hdc = GetDC (hWnd);
		lf.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
		lf.lfCharSet = ANSI_CHARSET;
		lf.lfWeight = FW_BOLD;
		lf.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
		strcpy (lf.lfFaceName, "Trebuchet MS");
		GameTitleFont = CreateFontIndirect (&lf);

		oldfont = SelectObject (hdc, GetStockObject (DEFAULT_GUI_FONT));
		GetTextMetrics (hdc, &tm);
		DefaultGUIFontHeight = tm.tmHeight;
		if (GameTitleFont == NULL)
		{
			GameTitleFontHeight = DefaultGUIFontHeight;
		}
		else
		{
			SelectObject (hdc, GameTitleFont);
			GetTextMetrics (hdc, &tm);
			GameTitleFontHeight = tm.tmHeight;
		}
		SelectObject (hdc, oldfont);

		// Create log read-only edit control
		view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "RichEdit20W", NULL,
			WS_CHILD | WS_VISIBLE | WS_VSCROLL |
			ES_LEFT | ES_MULTILINE | WS_CLIPSIBLINGS,
			0, 0, 0, 0,
			hWnd, NULL, inst, NULL);
		HRESULT hr;
		hr = GetLastError();
		if (view == NULL)
		{
			ReleaseDC (hWnd, hdc);
			return -1;
		}
		SendMessage (view, EM_SETREADONLY, TRUE, 0);
		SendMessage (view, EM_EXLIMITTEXT, 0, 0x7FFFFFFE);
		SendMessage (view, EM_SETBKGNDCOLOR, 0, RGB(70,70,70));
		// Setup default font for the log.
		//SendMessage (view, WM_SETFONT, (WPARAM)GetStockObject (DEFAULT_GUI_FONT), FALSE);
		format.cbSize = sizeof(format);
		format.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_CHARSET;
		format.dwEffects = 0;
		format.yHeight = 200;
		format.crTextColor = RGB(223,223,223);
		format.bCharSet = ANSI_CHARSET;
		format.bPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
		wcscpy(format.szFaceName, L"DejaVu Sans");	// At least I have it. :p
		SendMessageW(view, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format);

		ConWindow = view;
		ReleaseDC (hWnd, hdc);

		view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SS_OWNERDRAW, 0, 0, 0, 0, hWnd, NULL, inst, NULL);
		if (view == NULL)
		{
			return -1;
		}
		SetWindowLong (view, GWL_ID, IDC_STATIC_TITLE);
		GameTitleWindow = view;

		return 0;

	case WM_SIZE:
		if (wParam != SIZE_MAXHIDE && wParam != SIZE_MAXSHOW)
		{
			LayoutMainWindow (hWnd, ErrorPane);
		}
		return 0;

	case WM_DRAWITEM:
		// Draw title banner.
		if (wParam == IDC_STATIC_TITLE && DoomStartupInfo.Name.IsNotEmpty())
		{
			const PalEntry *c;

			// Draw the game title strip at the top of the window.
			drawitem = (LPDRAWITEMSTRUCT)lParam;

			// Draw the background.
			rect = drawitem->rcItem;
			rect.bottom -= 1;
			c = (const PalEntry *)&DoomStartupInfo.BkColor;
			hbr = CreateSolidBrush (RGB(c->r,c->g,c->b));
			FillRect (drawitem->hDC, &drawitem->rcItem, hbr);
			DeleteObject (hbr);

			// Calculate width of the title string.
			SetTextAlign (drawitem->hDC, TA_TOP);
			oldfont = SelectObject (drawitem->hDC, GameTitleFont != NULL ? GameTitleFont : (HFONT)GetStockObject (DEFAULT_GUI_FONT));
			titlelen = (int)DoomStartupInfo.Name.Len();
			GetTextExtentPoint32 (drawitem->hDC, DoomStartupInfo.Name, titlelen, &size);

			// Draw the title.
			c = (const PalEntry *)&DoomStartupInfo.FgColor;
			SetTextColor (drawitem->hDC, RGB(c->r,c->g,c->b));
			SetBkMode (drawitem->hDC, TRANSPARENT);
			TextOut (drawitem->hDC, rect.left + (rect.right - rect.left - size.cx) / 2, 2, DoomStartupInfo.Name, titlelen);
			SelectObject (drawitem->hDC, oldfont);
			return TRUE;
		}
		// Draw startup screen
		else if (wParam == IDC_STATIC_STARTUP)
		{
			if (StartupScreen != NULL)
			{
				drawitem = (LPDRAWITEMSTRUCT)lParam;

				rect = drawitem->rcItem;
				// Windows expects DIBs to be bottom-up but ours is top-down,
				// so flip it vertically while drawing it.
				StretchDIBits (drawitem->hDC, rect.left, rect.bottom - 1, rect.right - rect.left, rect.top - rect.bottom,
					0, 0, StartupBitmap->bmiHeader.biWidth, StartupBitmap->bmiHeader.biHeight,
					ST_Util_BitsForBitmap(StartupBitmap), StartupBitmap, DIB_RGB_COLORS, SRCCOPY);

				// If the title banner is gone, then this is an ENDOOM screen, so draw a short prompt
				// where the command prompt would have been in DOS.
				if (GameTitleWindow == NULL)
				{
					static const char QuitText[] = "Press any key or click anywhere in the window to quit.";

					SetTextColor (drawitem->hDC, RGB(240,240,240));
					SetBkMode (drawitem->hDC, TRANSPARENT);
					oldfont = SelectObject (drawitem->hDC, (HFONT)GetStockObject (DEFAULT_GUI_FONT));
					TextOut (drawitem->hDC, 3, drawitem->rcItem.bottom - DefaultGUIFontHeight - 3, QuitText, countof(QuitText)-1);
					SelectObject (drawitem->hDC, oldfont);
				}
				return TRUE;
			}
		}
		// Draw stop icon.
		else if (wParam == IDC_ICONPIC)
		{
			HICON icon;
			POINTL char_pos;
			drawitem = (LPDRAWITEMSTRUCT)lParam;

			// This background color should match the edit control's.
			hbr = CreateSolidBrush (RGB(70,70,70));
			FillRect (drawitem->hDC, &drawitem->rcItem, hbr);
			DeleteObject (hbr);

			// Draw the icon aligned with the first line of error text.
			SendMessage (ConWindow, EM_POSFROMCHAR, (WPARAM)&char_pos, ErrorIconChar);
			icon = (HICON)LoadImage (0, IDI_ERROR, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
			DrawIcon (drawitem->hDC, 6, char_pos.y, icon);
			return TRUE;
		}
		return FALSE;

	case WM_COMMAND:
		if (ErrorIcon != NULL && (HWND)lParam == ConWindow && HIWORD(wParam) == EN_UPDATE)
		{
			// Be sure to redraw the error icon if the edit control changes.
			InvalidateRect (ErrorIcon, NULL, TRUE);
			return 0;
		}
		break;

	case WM_CLOSE:
		PostQuitMessage (0);
		break;

	case WM_DESTROY:
		if (GameTitleFont != NULL)
		{
			DeleteObject (GameTitleFont);
		}
		break;
	}
	return DefWindowProc (hWnd, msg, wParam, lParam);
}
Example #11
0
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        
{
        
    static int   cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar ;
        
    static int   cLinesMax, cLines ;
        
    static PMSG  pmsg ;
        
    static RECT  rectScroll ;
        
    static TCHAR szTop[] = TEXT ("Message Key  Char ")
        
                                                          TEXT ("Repeat Scan Ext ALT Prev Tran") ;
        
    static TCHAR szUnd[] = TEXT ("_______        ___       ____     ")
        
                                                          TEXT ("______ ____ ___ ___ ____ ____") ;
        

    static TCHAR * szFormat[2] = {
        
                           TEXT ("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),
        
                           TEXT ("%-13s  0x%04X%1s%c %6u %4d %3s %3s %4s %4s") } ;
        
            static TCHAR * szYes  = TEXT ("Yes") ;
        
            static TCHAR * szNo   = TEXT ("No") ;
        
            static TCHAR * szDown = TEXT ("Down") ;
        
            static TCHAR * szUp   = TEXT ("Up") ;
        

            static TCHAR * szMessage [] = {
        
            TEXT ("WM_KEYDOWN"),  TEXT ("WM_KEYUP"),
        
            TEXT ("WM_CHAR"),     TEXT ("WM_DEADCHAR"),
        
            TEXT ("WM_SYSKEYDOWN"),TEXT ("WM_SYSKEYUP"),
        
            TEXT ("WM_SYSCHAR"),  TEXT ("WM_SYSDEADCHAR") } ;
        
            HDC                   hdc ;
        
            int                   i, iType ;
        
            PAINTSTRUCT           ps ;
        
            TCHAR                 szBuffer[128], szKeyName [32] ;
        
            TEXTMETRIC            tm ;
        
  
        
    switch (message)
        
    {
        
    case WM_CREATE:
        
    case WM_DISPLAYCHANGE:
        
                           // Get maximum size of client area
        
            cxClientMax = GetSystemMetrics (SM_CXMAXIMIZED) ;
        
            cyClientMax = GetSystemMetrics (SM_CYMAXIMIZED) ;
        

                           // Get character size for fixed-pitch font
        
            hdc = GetDC (hwnd) ;
        
            SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
        
            GetTextMetrics (hdc, &tm) ;
        
            cxChar = tm.tmAveCharWidth ;
        
            cyChar = tm.tmHeight ;
        

            ReleaseDC (hwnd, hdc) ;
        
                           // Allocate memory for display lines
        
            if (pmsg)
        
                   free (pmsg) ;
        
                   cLinesMax = cyClientMax / cyChar ;
        
                   pmsg = malloc (cLinesMax * sizeof (MSG)) ;
        
                   cLines = 0 ;
        
                   // fall through
        
    case WM_SIZE:
        
            if (message == WM_SIZE)
        
            {
        
                   cxClient = LOWORD (lParam) ;
        
                   cyClient = HIWORD (lParam) ;
        
            }
        
                                   // Calculate scrolling rectangle
        
            rectScroll.left       = 0 ;
        
            rectScroll.right      = cxClient ;
        
            rectScroll.top        = cyChar ;
        
            rectScroll.bottom     = cyChar * (cyClient / cyChar) ;
        

            InvalidateRect (hwnd, NULL, TRUE) ;
        
            return 0 ;
        
        
        
    case WM_KEYDOWN:
        
    case WM_KEYUP:
        
    case WM_CHAR:
        
    case WM_DEADCHAR:
        
    case WM_SYSKEYDOWN:
        
    case WM_SYSKEYUP:
        
    case WM_SYSCHAR:
        
    case WM_SYSDEADCHAR:
        
                                   // Rearrange storage array
        
            for (i = cLinesMax - 1 ; i > 0 ; i--)
        
            {
        
                           pmsg[i] = pmsg[i - 1] ;
        
            }
        
                                   // Store new message
        
            pmsg[0].hwnd = hwnd ;
        
            pmsg[0].message = message ;
        
            pmsg[0].wParam = wParam ;
        
            pmsg[0].lParam = lParam ;
        

            cLines = min (cLines + 1, cLinesMax) ;
        
                                   // Scroll up the display
        
            ScrollWindow (hwnd, 0, -cyChar, &rectScroll, &rectScroll) ;
        
            break ;               // i.e., call DefWindowProc so Sys messages work
        
    case WM_PAINT:
        
            hdc = BeginPaint (hwnd, &ps) ;
        
            SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
        
            SetBkMode (hdc, TRANSPARENT) ;
        
            TextOut (hdc, 0, 0, szTop, lstrlen (szTop)) ;
        
            TextOut (hdc, 0, 0, szUnd, lstrlen (szUnd)) ;
        

            for (i = 0 ; i < min (cLines, cyClient / cyChar - 1) ; i++)
        
            {
        
                   iType =       pmsg[i].message == WM_CHAR ||
        
                                   pmsg[i].message == WM_SYSCHAR ||
        
                                   pmsg[i].message == WM_DEADCHAR ||
        
                                   pmsg[i].message == WM_SYSDEADCHAR ;
        

                   GetKeyNameText (pmsg[i].lParam, szKeyName,
        
                                          sizeof (szKeyName) / sizeof (TCHAR)) ;
        

            TextOut (hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,
        
            wsprintf (szBuffer, szFormat [iType],
        
            szMessage [pmsg[i].message - WM_KEYFIRST],
        
            pmsg[i].wParam,
        
            (PTSTR) (iType ? TEXT (" ") : szKeyName),
        
            (TCHAR) (iType ? pmsg[i].wParam : ' '),
        
            LOWORD (pmsg[i].lParam),
        
            HIWORD (pmsg[i].lParam) & 0xFF,
        
                           0x01000000 & pmsg[i].lParam ? szYes  : szNo,
        
                           0x20000000 & pmsg[i].lParam ? szYes  : szNo,
        
                           0x40000000 & pmsg[i].lParam ? szDown : szUp,
        
                           0x80000000 & pmsg[i].lParam ? szUp   : szDown)) ;
        
            }
        
            EndPaint (hwnd, &ps) ;
        
            return 0 ;
        

    case   WM_DESTROY:
        
            PostQuitMessage (0) ;
        
            return 0 ;
        
    }
        
    return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
Example #12
0
long FAR PASCAL _export WndProc (HWND hwnd, UINT message, UINT wParam,
                                                          LONG lParam)
     {
     static short cxChar, cxCaps, cyChar, cyClient, nVscrollPos ;
     char         szBuffer[10] ;
     HDC          hdc ;
     short        i, y ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;

               SetScrollRange (hwnd, SB_VERT, 0, NUMLINES, FALSE) ;
               SetScrollPos   (hwnd, SB_VERT, nVscrollPos, TRUE) ;
               return 0 ;

          case WM_SIZE:
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_VSCROLL:
               switch (wParam)
                    {
                    case SB_LINEUP:
                         nVscrollPos -= 1 ;
                         break ;

                    case SB_LINEDOWN:
                         nVscrollPos += 1 ;
                         break ;

                    case SB_PAGEUP:
                         nVscrollPos -= cyClient / cyChar ;
                         break ;

                    case SB_PAGEDOWN:
                         nVscrollPos += cyClient / cyChar ;
                         break ;

                    case SB_THUMBPOSITION:
                         nVscrollPos = LOWORD (lParam) ;
                         break ;

                    default:
                         break ;
                    }
               nVscrollPos = max (0, min (nVscrollPos, NUMLINES)) ;

               if (nVscrollPos != GetScrollPos (hwnd, SB_VERT))
                    {
                    SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (i = 0 ; i < NUMLINES ; i++)
                    {
                    y = cyChar * (1 - nVscrollPos + i) ;

                    TextOut (hdc, cxChar, y,
                             sysmetrics[i].szLabel,
			     lstrlen (sysmetrics[i].szLabel)) ;

                    TextOut (hdc, cxChar + 22 * cxCaps, y,
                             sysmetrics[i].szDesc,
			     lstrlen (sysmetrics[i].szDesc)) ;

                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

                    TextOut (hdc, cxChar + 22 * cxCaps + 40 * cxChar, y,
                             szBuffer,
                             wsprintf (szBuffer, "%5d",
				  GetSystemMetrics (sysmetrics[i].nIndex))) ;

                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }
Example #13
0
LONG FAR PASCAL
MainMessageHandler(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    HDC        hDC;                     /* handle for the display device  */
    PAINTSTRUCT ps;                     /* holds PAINT information        */
    TEXTMETRIC tm;                      /* holds TEXT information         */

    static unsigned short *ADValues;    /* Win32 pointer                  */
    static HGLOBAL         MemHandle32;        
    static short           CurStatus;

    static HRGN     hRgn;                   /* Rectangle region Handles       */
    static int      CharWidth, CharHeight;
    static HGLOBAL  MemHandle; 
    int             x, y, i;
    long            Count, Rate;
    char            OutString[80], *str;
    float           Voltage;
    unsigned short  CurValue;


    switch (Message)                    /* Windows Message Loop           */
        {
        case WM_CREATE:
            hDC = GetDC(hWndMain);      /* Get the device context for window */
            GetTextMetrics(hDC, &tm);   /* From context, get size of font */
            CharWidth = tm.tmAveCharWidth;
            CharHeight = tm.tmHeight + tm.tmExternalLeading;
            ReleaseDC(hWndMain, hDC);
            hRgn = CreateRectRgn(0,0, CharWidth*30, CharHeight*20);    

            /* Allocate a Windows buffer */
            MemHandle = cbWinBufAlloc ((long)BUF_SIZE);

            /* WIN32: This code is added to be able access more than  */
            /* 32K words of data.                                     */
            
            /* WIN32: allocate a local WIN32 buffer to hold A/D Data  */
             MemHandle32 = GlobalAlloc(GMEM_FIXED | GMEM_DDESHARE, BUF_SIZE *sizeof(short));
				
            /* Get a 32-bit pointer to the WIN32 buffer */
            ADValues = (unsigned short *)GlobalLock(MemHandle32);
            
            /* Start up A/D scan */
            Count = BUF_SIZE;
            Rate = BUF_SIZE / NUM_SECS;
            cbAInScan (BOARD_NUM, 0, 0, Count, &Rate, ADRANGE, MemHandle,
                       CONVERTDATA);
            break;


        case WM_PAINT:                  /* Repaint client area of window */
            hDC = BeginPaint(hWndMain, &ps);     
            
            x = CharWidth * 2;          /* Position cursor within window */     
            y = CharHeight;             /* One line down and 2 chars in */
            str = "         A/D Info";  /* Print title */
            TextOut(hDC, x, y, str, strlen (str));

			Count = BUF_SIZE;
			/* Copy Data from memory to 32-bit memory buffer */
			cbWinBufToArray( MemHandle, &ADValues[0], 0, Count );

            for (i=0;i<=4;i++)
                {
                CurValue = ADValues[i];
                y       += CharHeight*2;            /* Print raw data value */
                sprintf (OutString,"Raw A/D value(%d) = %u    ", i, CurValue);
                TextOut(hDC, x, y, OutString, strlen (OutString));
                                    
                y       += CharHeight;    /* Convert raw A/D to volts and print */
                cbToEngUnits(BOARD_NUM,ADRANGE,CurValue,&Voltage);
                sprintf (OutString,"Voltage = %.2f    ", Voltage);
                TextOut(hDC, x, y, OutString, strlen (OutString));
                }
                
            SetTextAlign(hDC, TA_LEFT | TA_TOP);
            EndPaint(hWndMain, &ps);
            break;

        case WM_CLOSE:                      /* Close the window */
            DestroyWindow(hWnd);                          
            if (hWnd == hWndMain)
                PostQuitMessage(0);         /* Send message to Quit application */
            if (MemHandle)                  
                cbWinBufFree (MemHandle);   /* Free allocated memory */

			if ( MemHandle32 )
				GlobalFree( MemHandle32 );
			break;

        default:
            return (DefWindowProc(hWnd, Message, wParam, lParam));
        }
    return (0l);
}
Example #14
0
/* initialize the process.  Reads the init files to get the appropriate
 * information. */
BOOL InitInstance(
	HANDLE hInstance,
	int nCmdShow)
{
	HWND hWnd;
	HDC hDC;
	TEXTMETRIC textmetric;
	INT nLineHeight;
    long code, cnt;
	char *reason;
 
	/* remember this, since it is a useful thing for some of the Windows
	 * calls */
	main_inst = hInstance;

	/* create our window */
	hWnd = CreateWindow(
		"AFSDWinClass",
	        "AFSD",
	        WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
	        CW_USEDEFAULT,
	        CW_USEDEFAULT,
	        CW_USEDEFAULT,
	        CW_USEDEFAULT,
	        NULL,
	        NULL,
	        hInstance,
	        NULL
	);

	if (!hWnd)
	        return (FALSE);

	/* lookup text dimensions */
	hDC = GetDC(hWnd);
	GetTextMetrics(hDC, &textmetric);
	nLineHeight = textmetric.tmExternalLeading + textmetric.tmHeight;
	
	main_rect.left   = GetDeviceCaps(hDC, LOGPIXELSX) / 4;   /* 1/4 inch */
	main_rect.right  = GetDeviceCaps(hDC, HORZRES);
	main_rect.top    = GetDeviceCaps(hDC, LOGPIXELSY) / 4;   /* 1/4 inch */
	ReleaseDC(hWnd, hDC);
	main_rect.bottom = main_rect.top + nLineHeight;

	osi_InitPanic(afsd_notifier);

	afsi_start();

        code = afsd_InitCM(&reason);
	if (code != 0)
		osi_panic(reason, __FILE__, __LINE__);

	code = afsd_InitDaemons(&reason);
	if (code != 0)
		osi_panic(reason, __FILE__, __LINE__);

        code = afsd_InitSMB(&reason, MessageBox);

	if (code != 0)
            osi_panic(reason, __FILE__, __LINE__);

	ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
	UpdateWindow(hWnd);
	return (TRUE);
}
Example #15
0
int Wout::GetAverageTextWidth()
{
	GetTextMetrics(hDC, &textInfo);
	return textInfo.tmAveCharWidth;
}
Example #16
0
void PaintClc(HWND hwnd, struct ClcData *dat, HDC hdc, RECT * rcPaint)
{
	HDC hdcMem;
	RECT clRect;
	int y, indent, index, fontHeight;
	struct ClcGroup *group;
	HFONT hOldFont;
	DWORD style = GetWindowLong(hwnd, GWL_STYLE);
	int status = GetGeneralisedStatus();
	int grey = 0, groupCountsFontTopShift;
	HBRUSH hBrushAlternateGrey = NULL;
	// yes I know about GetSysColorBrush()
	COLORREF tmpbkcolour = style & CLS_CONTACTLIST ? (dat->useWindowsColours ? GetSysColor(COLOR_3DFACE) : dat->bkColour) : dat->bkColour;

	if (dat->greyoutFlags & pcli->pfnClcStatusToPf2(status) || style & WS_DISABLED)
		grey = 1;
	else if (GetFocus() != hwnd && dat->greyoutFlags & GREYF_UNFOCUS)
		grey = 1;
	GetClientRect(hwnd, &clRect);
	if (rcPaint == NULL)
		rcPaint = &clRect;
	if (IsRectEmpty(rcPaint))
		return;
	y = -dat->yScroll;
	hdcMem = CreateCompatibleDC(hdc);
	HBITMAP hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
	HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBmpOsb);
	{
		TEXTMETRIC tm;
		hOldFont = (HFONT)SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPS].hFont);
		GetTextMetrics(hdcMem, &tm);
		groupCountsFontTopShift = tm.tmAscent;
		SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPCOUNTS].hFont);
		GetTextMetrics(hdcMem, &tm);
		groupCountsFontTopShift -= tm.tmAscent;
	}
	if (style & CLS_GREYALTERNATE)
		hBrushAlternateGrey =
		CreateSolidBrush(GetNearestColor(hdcMem, RGB(GetRValue(tmpbkcolour) - 10, GetGValue(tmpbkcolour) - 10, GetBValue(tmpbkcolour) - 10)));

	ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
	SetBkMode(hdcMem, TRANSPARENT);
	{
		HBRUSH hBrush;

		hBrush = CreateSolidBrush(tmpbkcolour);
		FillRect(hdcMem, rcPaint, hBrush);
		DeleteObject(hBrush);
		if (dat->hBmpBackground) {
			BITMAP bmp;
			HDC hdcBmp;
			int x, y;
			int maxx, maxy;
			int destw, desth;

			// XXX: Halftone isnt supported on 9x, however the scretch problems dont happen on 98.
			SetStretchBltMode(hdcMem, HALFTONE);

			GetObject(dat->hBmpBackground, sizeof(bmp), &bmp);
			hdcBmp = CreateCompatibleDC(hdcMem);
			SelectObject(hdcBmp, dat->hBmpBackground);
			y = dat->backgroundBmpUse & CLBF_SCROLL ? -dat->yScroll : 0;
			maxx = dat->backgroundBmpUse & CLBF_TILEH ? clRect.right : 1;
			maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rcPaint->bottom : y + 1;
			switch (dat->backgroundBmpUse & CLBM_TYPE) {
			case CLB_STRETCH:
				if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
					if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) {
						desth = clRect.bottom;
						destw = desth * bmp.bmWidth / bmp.bmHeight;
					}
					else {
						destw = clRect.right;
						desth = destw * bmp.bmHeight / bmp.bmWidth;
					}
				}
				else {
					destw = clRect.right;
					desth = clRect.bottom;
				}
				break;
			case CLB_STRETCHH:
				if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
					destw = clRect.right;
					desth = destw * bmp.bmHeight / bmp.bmWidth;
				}
				else {
					destw = clRect.right;
					desth = bmp.bmHeight;
				}
				break;
			case CLB_STRETCHV:
				if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
					desth = clRect.bottom;
					destw = desth * bmp.bmWidth / bmp.bmHeight;
				}
				else {
					destw = bmp.bmWidth;
					desth = clRect.bottom;
				}
				break;
			default:       //clb_topleft
				destw = bmp.bmWidth;
				desth = bmp.bmHeight;
				break;
			}
			for (; y < maxy; y += desth) {
				if (y < rcPaint->top - desth)
					continue;
				for (x = 0; x < maxx; x += destw)
					StretchBlt(hdcMem, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
			}
			DeleteDC(hdcBmp);
		}
	}
	group = &dat->list;
	group->scanIndex = 0;
	indent = 0;
	for (index = 0; y < rcPaint->bottom;) {
		if (group->scanIndex == group->cl.count) {
			group = group->parent;
			indent--;
			if (group == NULL)
				break;
			group->scanIndex++;
			continue;
		}
		if (y > rcPaint->top - dat->rowHeight) {
			int iImage = -1;
			int selected = index == dat->selection && (dat->showSelAlways || dat->exStyle & CLS_EX_SHOWSELALWAYS || GetFocus() == hwnd)
				&& group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER;
			int hottrack = dat->exStyle & CLS_EX_TRACKSELECT && group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER && dat->iHotTrack == index;
			SIZE textSize, countsSize, spaceSize;
			int width, checkboxWidth;
			char *szCounts;

			//alternating grey
			if (style & CLS_GREYALTERNATE && index & 1) {
				RECT rc;
				rc.top = y;
				rc.bottom = rc.top + dat->rowHeight;
				rc.left = 0;
				rc.right = clRect.right;
				FillRect(hdcMem, &rc, hBrushAlternateGrey);
			}

			//setup
			if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP)
				ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
			else if (group->cl.items[group->scanIndex]->type == CLCIT_INFO) {
				if (group->cl.items[group->scanIndex]->flags & CLCIIF_GROUPFONT)
					ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
				else
					ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
			}
			else if (group->cl.items[group->scanIndex]->type == CLCIT_DIVIDER)
				ChangeToFont(hdcMem, dat, FONTID_DIVIDERS, &fontHeight);
			else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST)
				ChangeToFont(hdcMem, dat, FONTID_NOTONLIST, &fontHeight);
			else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT &&
				((group->cl.items[group->scanIndex]->flags & CONTACTF_INVISTO
				&& GetRealStatus(group->cl.items[group->scanIndex], status) != ID_STATUS_INVISIBLE)
				|| (group->cl.items[group->scanIndex]->flags & CONTACTF_VISTO
				&& GetRealStatus(group->cl.items[group->scanIndex], status) == ID_STATUS_INVISIBLE)
				)
				) {
					// the contact is in the always visible list and the proto is invisible
					// the contact is in the always invisible and the proto is in any other mode
					ChangeToFont(hdcMem, dat, group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE ? FONTID_INVIS : FONTID_OFFINVIS, &fontHeight);
				}
			else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && !(group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE))
				ChangeToFont(hdcMem, dat, FONTID_OFFLINE, &fontHeight);
			else
				ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
			GetTextExtentPoint32(hdcMem, group->cl.items[group->scanIndex]->szText, lstrlen(group->cl.items[group->scanIndex]->szText), &textSize);
			width = textSize.cx;
			if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
				szCounts = pcli->pfnGetGroupCountsText(dat, group->cl.items[group->scanIndex]);
				if (szCounts[0]) {
					GetTextExtentPoint32A(hdcMem, " ", 1, &spaceSize);
					ChangeToFont(hdcMem, dat, FONTID_GROUPCOUNTS, &fontHeight);
					GetTextExtentPoint32A(hdcMem, szCounts, lstrlenA(szCounts), &countsSize);
					width += spaceSize.cx + countsSize.cx;
				}
			}

			if ((style & CLS_CHECKBOXES && group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) ||
				(style & CLS_GROUPCHECKBOXES && group->cl.items[group->scanIndex]->type == CLCIT_GROUP) ||
				(group->cl.items[group->scanIndex]->type == CLCIT_INFO && group->cl.items[group->scanIndex]->flags & CLCIIF_CHECKBOX))
				checkboxWidth = dat->checkboxSize + 2;
			else
				checkboxWidth = 0;

			//background
			if (selected) {
				int x = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace - 2;
				ImageList_DrawEx(dat->himlHighlight, 0, hdcMem, x, y, min(width + 5, clRect.right - x), dat->rowHeight, CLR_NONE, CLR_NONE,
					dat->exStyle & CLS_EX_NOTRANSLUCENTSEL ? ILD_NORMAL : ILD_BLEND25);
				SetTextColor(hdcMem, dat->selTextColour);
			}
			else if (hottrack)
				SetHotTrackColour(hdcMem, dat);

			//checkboxes
			if (checkboxWidth) {
				RECT rc;
				HANDLE hTheme = OpenThemeData(hwnd, L"BUTTON");
				rc.left = dat->leftMargin + indent * dat->groupIndent;
				rc.right = rc.left + dat->checkboxSize;
				rc.top = y + ((dat->rowHeight - dat->checkboxSize) >> 1);
				rc.bottom = rc.top + dat->checkboxSize;
				DrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, group->cl.items[group->scanIndex]->flags & CONTACTF_CHECKED ? (hottrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : (hottrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL), &rc, &rc);
				CloseThemeData(hTheme);
			}

			//icon
			if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP)
				iImage = group->cl.items[group->scanIndex]->group->expanded ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT;
			else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT)
				iImage = group->cl.items[group->scanIndex]->iImage;
			if (iImage != -1) {
				/*COLORREF colourFg=dat->selBkColour;
				int mode=ILD_NORMAL;
				if(selected) mode=ILD_SELECTED;
				else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;}
				else if(group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;}
				ImageList_DrawEx(himlCListClc,iImage,hdcMem,dat->leftMargin+indent*dat->groupIndent+checkboxWidth,y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode);
				*/
				// this doesnt use CLS_CONTACTLIST since the colour prolly wont match anyway
				COLORREF colourFg = dat->selBkColour;
				int mode = ILD_NORMAL;
				if (hottrack) {
					colourFg = dat->hotTextColour;
				}
				else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST) {
					colourFg = dat->fontInfo[FONTID_NOTONLIST].colour;
					mode = ILD_BLEND50;
				}
				if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && dat->showIdle
					&& (group->cl.items[group->scanIndex]->flags & CONTACTF_IDLE)
					&& GetRealStatus(group->cl.items[group->scanIndex], ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
					mode = ILD_SELECTED;
				ImageList_DrawEx(himlCListClc, iImage, hdcMem, dat->leftMargin + indent * dat->groupIndent + checkboxWidth,
					y + ((dat->rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode);
			}

			//text
			if (group->cl.items[group->scanIndex]->type == CLCIT_DIVIDER) {
				RECT rc;
				rc.top = y + (dat->rowHeight >> 1);
				rc.bottom = rc.top + 2;
				rc.left = dat->leftMargin + indent * dat->groupIndent;
				rc.right = rc.left + ((clRect.right - rc.left - textSize.cx) >> 1) - 3;
				DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
				TextOut(hdcMem, rc.right + 3, y + ((dat->rowHeight - fontHeight) >> 1), group->cl.items[group->scanIndex]->szText,
					lstrlen(group->cl.items[group->scanIndex]->szText));
				rc.left = rc.right + 6 + textSize.cx;
				rc.right = clRect.right;
				DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
			}
Example #17
0
int Wout::GetTextHeight()
{
	GetTextMetrics(hDC, &textInfo);
	return textInfo.tmHeight;
}
Example #18
0
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
    {
    WNDCLASS    wc;
    HWND        hWnd;
    MSG         msg;
    TEXTMETRIC  tm;
    HDC         hDC;
    LONG        cxFont;
    LONG        cyFont;


    if (!hPrevInstance)
        {
        wc.style          = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc    = MusTestWndProc;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hInstance      = hInstance;
        wc.hIcon          = LoadIcon(hInstance, "MusTestIcon");
        wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName   = "MusTestMenu";
        wc.lpszClassName  = "MusTest";


        if (!RegisterClass(&wc))
            return FALSE;
        }


    //Create and show main window.
    hWnd=CreateWindow("MusTest", "MicroScrolls",
                      WS_MINIMIZEBOX | WS_OVERLAPPEDWINDOW,
                      35, 35, 250, 110,
                      NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    //Get text dimensions on which to base control sizes.
    hDC=GetDC(hWnd);
    GetTextMetrics(hDC, &tm);
    cxFont=tm.tmAveCharWidth;
    cyFont=tm.tmHeight;
    ReleaseDC(hWnd, hDC);

    //Create a 'spin' button (edit control with vertical MicroScroll
    CreateWindow("static", "Number 1-99:",
                 WS_VISIBLE | WS_CHILD | SS_LEFT,
                 2,   2+(cyFont/4), 16*cxFont, cyFont,
		 hWnd, (HMENU)ID_NULL, hInstance, 0L);

    hVertEdit=CreateWindow("edit", "50",
                 WS_VISIBLE | WS_CHILD | ES_LEFT | WS_BORDER,
                 2+16*cxFont, 2, 4*cxFont, (cyFont*3)/2,
                 hWnd, (HMENU)ID_VERTEDIT, hInstance, 0L);

    SendMessage(hVertEdit, EM_LIMITTEXT, 2, 0L);

    /*
     * Width is forced odd with 1+(2*cxFont) so the small triangle
     * looks perfectly centered.  Simple aesthetics.
     *
     * Parent window is default associate.
     */
    hVertMS=CreateWindow("MicroScroll32", "1,99,50",
                 WS_VISIBLE | WS_CHILD | MSS_SPIN,
                 2+20*cxFont, 2, 1+(2*cxFont), (cyFont*3)/2,
                 hWnd, (HMENU)ID_VERTSCROLL, hInstance, 0L);

    //Create a horizonal edit control with a horizontal MicroScroll
    hHorzEdit=CreateWindow("edit", "Horizontal Edit Control",
                 WS_VISIBLE | WS_CHILD | ES_LEFT | WS_BORDER,
                 2, 2*cyFont, 30*cxFont, (cyFont*3)/2,
                 hWnd, (HMENU)ID_VERTEDIT, hInstance, 0L);

    //Parent window is default associate.
    hHorzMS=CreateWindow("MicroScroll32", "1,99,50",
                 WS_VISIBLE | WS_CHILD | MSS_HORIZONTAL,
                 2+30*cxFont, 2*cyFont, 3*cxFont, (cyFont*3)/2,
                 hWnd, (HMENU)ID_HORZSCROLL, hInstance, 0L);

    //Change the horizontal MicroScroll colors to a blue base.
    MSCrColorSet(hHorzMS, MSCOLOR_FACE,      RGB(0,   0,   255));
    MSCrColorSet(hHorzMS, MSCOLOR_ARROW,     RGB(255, 255, 255));
    MSCrColorSet(hHorzMS, MSCOLOR_SHADOW,    RGB(0,   0,   128));
    MSCrColorSet(hHorzMS, MSCOLOR_HIGHLIGHT, RGB(0,   255, 255));

    while (GetMessage(&msg, NULL, 0, 0))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }

    return msg.wParam;
    }
Example #19
0
Wout & Wout::operator << (const TCHAR * szText) 
{			 
	// Error Checking on
	if (window == NULL || hDC == NULL)
	{
		MessageBox(NULL, _T("hDC or m_hWnd is NULL in Wout object"), _T("Bad Error Yo!"), MB_ICONEXCLAMATION | MB_OK); 
		return (*this);
	}
	
	GetTextMetrics(hDC, &textInfo);
	::SetTextColor(hDC, m_TextColor);
	SetBkMode(hDC, TRANSPARENT); // AD_TODO: this shouldn't be a constant, change it to a variable
	
	m_CtstringToPrint = szText;
	m_currtstringPos = 0;

	RECT rect;
	GetClientRect(window, &rect);
	
	if ( centerText )
	{
		SetCursorY(rect.bottom/2 - GetTextHeight()/2);
		SetCursorX(rect.right/2 - (GetAverageTextWidth()*tstrlen(szText))/2);
		centerText = false;
	}
	if (centerX)
	{
		SetCursorX(rect.right/2 - (GetAverageTextWidth()*tstrlen(szText))/2);
		centerX = false;
	}

	// Algorithm to put text on screen :)
	while (1)
	{
		if (m_currtstringPos == m_CtstringToPrint.size())
		{
			break;
		}
		
		int indexFound = (int)m_CtstringToPrint.find_first_of('\\', m_currtstringPos); 
		
		if (indexFound == tstring::npos)
		{
			int tstringSizeToPrint = (int)m_CtstringToPrint.size() - m_currtstringPos;
			// Print it
			::SetTextColor(hDC, m_TextColor);
			TextOut(hDC, 
					m_CursorPosX + hdcOffsetX, 
					m_CursorPosY + hdcOffsetY, 
					m_CtstringToPrint.substr(m_currtstringPos, tstringSizeToPrint).c_str(), 
					tstringSizeToPrint);
			m_CursorPosX += tstringSizeToPrint*textInfo.tmAveCharWidth; 
			break;
		}
		else
		{
			// so we found some delimiter x indices away from our current tstring position.
			// lets print the tstring up until that index(delimiter), 
			// then we will take care of the delimiter in the InitDelimiter function
			// and then well go to the top of this loop, until we are done with the tstring.
			int tstringSizeToPrint = (indexFound) - m_currtstringPos;
			// Print it
			::SetTextColor(hDC, m_TextColor);
			TextOut(hDC, 
					m_CursorPosX + hdcOffsetX, 
					m_CursorPosY + hdcOffsetY, 
					m_CtstringToPrint.substr(m_currtstringPos, tstringSizeToPrint).c_str(), 
					tstringSizeToPrint);
			m_CursorPosX += tstringSizeToPrint*textInfo.tmAveCharWidth; 

			m_currtstringPos += tstringSizeToPrint; // so now we're pointing at the delimiter
			InitDelim();
			continue;
		}
	}

	return (*this); 
}
Example #20
0
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int  cxChar, cxCaps, cyChar, cyClient, 
		iVscrollPos = 0;//滑块当前位置
	HDC         hdc;
	int         i, y;
	PAINTSTRUCT ps;
	TCHAR       szBuffer[10];
	TEXTMETRIC  tm;

	switch (message)
	{
	case WM_CREATE:
		hdc = GetDC(hwnd);

		GetTextMetrics(hdc, &tm);
		cxChar = tm.tmAveCharWidth;
		cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
		cyChar = tm.tmHeight + tm.tmExternalLeading;

		ReleaseDC(hwnd, hdc);

		SetScrollRange(hwnd, SB_VERT, 0, NUMLINES - 1, FALSE);//范围
		SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);//初始位置
		return 0;

	case WM_SIZE:
		cyClient = HIWORD(lParam);
		return 0;

	case WM_VSCROLL:
		switch (LOWORD(wParam))
		{
		case SB_LINEUP://点滚动条上方的小箭头
			iVscrollPos -= 1;
			break;

		case SB_LINEDOWN://点滚动条下方的小箭头
			iVscrollPos += 1;
			break;

		case SB_PAGEUP://在滚动条上方点空白位置
			iVscrollPos -= cyClient / cyChar;
			break;

		case SB_PAGEDOWN://在滚动条下方点空白位置
			iVscrollPos += cyClient / cyChar;
			break;

		case SB_THUMBPOSITION://在滚动条上松开鼠标
			iVscrollPos = HIWORD(wParam);//这里用上了wParam
			break;

		default:
			break;
		}

		iVscrollPos = max(0, min(iVscrollPos, NUMLINES - 1));

		if (iVscrollPos != GetScrollPos(hwnd, SB_VERT))//获取当前的位置
		{
			SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);//更新数值
			InvalidateRect(hwnd, NULL, TRUE);//刷新界面
		}
		return 0;

	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);

		for (i = 0; i < NUMLINES; i++)
		{
			y = cyChar * (i - iVscrollPos);

			TextOut(hdc, 0, y,
				sysmetrics[i].szLabel,
				lstrlen(sysmetrics[i].szLabel));

			TextOut(hdc, 22 * cxCaps, y,
				sysmetrics[i].szDesc,
				lstrlen(sysmetrics[i].szDesc));

			SetTextAlign(hdc, TA_RIGHT | TA_TOP);

			TextOut(hdc, 22 * cxCaps + 40 * cxChar, y, szBuffer,
				wsprintf(szBuffer, TEXT("%5d"),
					GetSystemMetrics(sysmetrics[i].iIndex)));

			SetTextAlign(hdc, TA_LEFT | TA_TOP);
		}
		EndPaint(hwnd, &ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}
Example #21
0
void FASTCALL MakeEditSelectionVisible( HWND hwndTopWnd, HWND hwndEdit )
{

#ifdef USEBIGEDIT
   RECT rcTopWnd;
   RECT rcEdit;
   RECT rcEditNC;
   RECT rcOverlap;
   RECT rcSelOverlap;
   RECT rcSel;
   int nSelStartOffset;
   int nSelEndOffset;
   int nEditLineHeight;
   BEC_SELECTION bsel;
   HEDIT hedit;
   TEXTMETRIC tm;
   HFONT hwndEditFont;
   HFONT hOldFont;
   int nDist;
   HDC hdc;

   /* First of all, compute the overlap. If no overlap, then
    * we don't have to do anything further.
    */
   GetWindowRect( hwndTopWnd, &rcTopWnd );
   GetWindowRect( hwndEdit, &rcEdit );
   if( IntersectRect( &rcOverlap, &rcTopWnd, &rcEdit ) == 0 )
      return;

   /* Compute the screen coordinates of the edit selection (!)
    * Only bother with the top and bottom edges.
    */
   hedit = Editmap_Open( hwndEdit );
   Editmap_GetSelection( hedit, hwndEdit, &bsel );
   nSelStartOffset = (int)( Editmap_LineFromChar( hedit, hwndEdit, bsel.lo ) - Editmap_GetFirstVisibleLine( hedit, hwndEdit ) );
   nSelEndOffset = (int)( Editmap_LineFromChar( hedit, hwndEdit, bsel.lo ) - Editmap_GetFirstVisibleLine( hedit, hwndEdit ) );
   hwndEditFont = GetWindowFont( hwndEdit );
   hdc = GetDC( hwndEdit );
   hOldFont = SelectFont( hdc, hwndEditFont );
   GetTextMetrics( hdc, &tm );
   SelectFont( hdc, hOldFont );
   ReleaseDC( hwndEdit, hdc );
   nEditLineHeight = tm.tmHeight;
   SetRect( &rcSel, 0, nSelStartOffset * nEditLineHeight, rcEdit.right - rcEdit.left, ( nSelEndOffset + 1 ) * nEditLineHeight );
   Editmap_GetRect( hedit, hwndEdit, &rcEditNC );
   ClientToScreen( hwndEdit, (LPPOINT)&rcSel );
   ClientToScreen( hwndEdit, (LPPOINT)(&rcSel) + 1 );
   rcSel.top += rcEditNC.top;
   rcSel.bottom += rcEditNC.top;

   /* Does the selection rectangle intesect the overlap?
    * If so, scroll the edit control down by the distance between the selection top edge
    * and the top window bottom edge.
    */
   if( IntersectRect( &rcSelOverlap, &rcOverlap, &rcSel ) == 0 )
      return;
   if( rcEdit.bottom > rcTopWnd.bottom )
      nDist = -( ( ( rcTopWnd.bottom - rcSel.top ) / nEditLineHeight ) + 1 );
   else
      nDist = ( ( rcSel.bottom - rcTopWnd.top ) / nEditLineHeight ) + 1;

   if( (long)Editmap_GetFirstVisibleLine( hedit, hwndEdit ) + nDist >= 0 )
      {
      Editmap_Scroll( hedit, hwndEdit, nDist, 0 );
      return;
      }

   /* Okay. We can't scroll the edit control because the top window is completely
    * overlapping the edit control, or the scroll would go past the first line. So
    * try and move the top window.
    */
   if( rcEdit.bottom > rcTopWnd.bottom )
      nDist = rcTopWnd.top - ( rcSel.bottom + ( 2 * nEditLineHeight ) );
   else
      nDist = ( rcTopWnd.top - rcSel.bottom ) + 1;
   if( rcTopWnd.top - nDist < 0 )
      nDist = rcTopWnd.top - rcSel.bottom;
   else if( rcTopWnd.bottom - nDist > GetSystemMetrics( SM_CYSCREEN ) )
      nDist = rcTopWnd.bottom - rcSel.top;
   SetWindowPos( hwndTopWnd, NULL, rcTopWnd.left, rcTopWnd.top - nDist, 0, 0, SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER );

#else USEBIGEDIT

   HEDIT hedit;
   BEC_SELECTION bsel;
   SELRANGE lLine, lCurLine; 

   hedit = Editmap_Open( hwndEdit );

   Editmap_GetSelection( hedit, hwndEdit, &bsel );

   lLine = Editmap_LineFromChar( hedit, hwndEdit, bsel.hi );
   lCurLine = Editmap_GetFirstVisibleLine( hedit, hwndEdit );

   if( lCurLine >= lLine )
   {
      SendMessage( hwndEdit, SCI_GOTOPOS, bsel.hi, 0);
      Editmap_SetSel( hedit, hwndEdit, &bsel );
//    Editmap_Scroll( hedit, hwndEdit, lLine, 0 );
      return;
   }

   SendMessage( hwndEdit, SCI_MOVECARETINSIDEVIEW, 0, 0);


#endif USEBIGEDIT
}
BOOL CTextLayout::Layout(HDC hdc, const WCHAR *psz,  UINT nCnt)
{
    Clear();

    // Count Line
    UINT i = 0;
    BOOL bNewLine = TRUE;
    _nLineCnt = 0;
    for (i = 0; i < nCnt; i++)
    {
        switch (psz[i])
        {
            case 0x0d:
            case 0x0a:
                bNewLine = TRUE;
                break;
            default:
                if (bNewLine)
                    _nLineCnt++;
                bNewLine = FALSE;
                break;
        }
    }

    _prgLines = (LINEINFO *)LocalAlloc(LPTR, _nLineCnt * sizeof(LINEINFO));
    if (!_prgLines)
        return FALSE;

    // Count character of each line.
    bNewLine = TRUE;
    int nCurrentLine = -1;
    for (i = 0; i < nCnt; i++)
    {
        switch (psz[i])
        {
            case 0x0d:
            case 0x0a:
                bNewLine = TRUE;
                break;
            default:
                if (bNewLine)
                {
                    nCurrentLine++;
                    _prgLines[nCurrentLine].nPos = i;
                    _prgLines[nCurrentLine].nCnt = 1;
                }
                else
                {
                    _prgLines[nCurrentLine].nCnt++;
                }
                bNewLine = FALSE;
                break;
        }
    }

    TEXTMETRIC tm;
    GetTextMetrics(hdc, &tm);
    _nLineHeight = tm.tmHeight + tm.tmExternalLeading;

    POINT ptCurrent;
    ptCurrent.x = 0;
    ptCurrent.y = 0;

    // Get the rectangle of each characters.
    for (i = 0; i < _nLineCnt; i++)
    {
        _prgLines[i].prgCharInfo = NULL;

        if (_prgLines[i].nCnt)
        {
            _prgLines[i].prgCharInfo = (CHARINFO *)LocalAlloc(LPTR, _prgLines[i].nCnt * sizeof(CHARINFO));
            if (!_prgLines[i].prgCharInfo)
                return FALSE;

            UINT j;
            POINT ptPrev = ptCurrent;
            for (j = 0; j < _prgLines[i].nCnt; j++)
            {
                SIZE size;
                GetTextExtentPoint32(hdc, psz+_prgLines[i].nPos, j + 1, &size);
                ptCurrent.x = size.cx;
                _prgLines[i].prgCharInfo[j].rc.left = ptPrev.x;
                _prgLines[i].prgCharInfo[j].rc.top = ptPrev.y;
                _prgLines[i].prgCharInfo[j].rc.right = ptCurrent.x;
                _prgLines[i].prgCharInfo[j].rc.bottom = ptPrev.y + _nLineHeight;

                ptPrev = ptCurrent;
            }
        }

        ptCurrent.x = 0;
        ptCurrent.y += _nLineHeight;
    }
    return TRUE;
}
Example #23
0
/*
** This is cribbed from FX/fxwgl.c, and seems to implement support
** for bitmap fonts where the wglUseFontBitmapsA() code implements
** support for outline fonts.  In combination they hopefully give
** fairly generic support for fonts.
*/
static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
                                 DWORD numChars, DWORD listBase)
{
#define VERIFY(a) a
    
    TEXTMETRIC metric;
    BITMAPINFO *dibInfo;
    HDC bitDevice;
    COLORREF tempColor;
    int i;
    
    VERIFY(GetTextMetrics(fontDevice, &metric));
    
    dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
    dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    dibInfo->bmiHeader.biPlanes = 1;
    dibInfo->bmiHeader.biBitCount = 1;
    dibInfo->bmiHeader.biCompression = BI_RGB;
    
    bitDevice = CreateCompatibleDC(fontDevice);
    
    // Swap fore and back colors so the bitmap has the right polarity
    tempColor = GetBkColor(bitDevice);
    SetBkColor(bitDevice, GetTextColor(bitDevice));
    SetTextColor(bitDevice, tempColor);
    
    // Place chars based on base line
    VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0);
    
    for(i = 0; i < (int)numChars; i++) {
	SIZE size;
	char curChar;
	int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
	HBITMAP bitObject;
	HGDIOBJ origBmap;
	unsigned char *bmap;
	
	curChar = (char)(i + firstChar);
	
	// Find how high/wide this character is
	VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
	
	// Create the output bitmap
	charWidth = size.cx;
	charHeight = size.cy;
	// Round up to the next multiple of 32 bits
	bmapWidth = ((charWidth + 31) / 32) * 32;   
	bmapHeight = charHeight;
	bitObject = CreateCompatibleBitmap(bitDevice,
					   bmapWidth,
					   bmapHeight);
	//VERIFY(bitObject);
	
	// Assign the output bitmap to the device
	origBmap = SelectObject(bitDevice, bitObject);
	(void) VERIFY(origBmap);
	
	VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
	
	// Use our source font on the device
	VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
	
	// Draw the character
	VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
	
	// Unselect our bmap object
	VERIFY(SelectObject(bitDevice, origBmap));
	
	// Convert the display dependant representation to a 1 bit deep DIB
	numBytes = (bmapWidth * bmapHeight) / 8;
	bmap = malloc(numBytes);
	dibInfo->bmiHeader.biWidth = bmapWidth;
	dibInfo->bmiHeader.biHeight = bmapHeight;
	res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
			dibInfo,
			DIB_RGB_COLORS);
	//VERIFY(res);
	
	// Create the GL object
	glNewList(i + listBase, GL_COMPILE);
	glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent,
		 (GLfloat)charWidth, 0.0,
		 bmap);
	glEndList();
	// CheckGL();
	
	// Destroy the bmap object
	DeleteObject(bitObject);
	
	// Deallocate the bitmap data
	free(bmap);
    }
    
    // Destroy the DC
    VERIFY(DeleteDC(bitDevice));
    
    free(dibInfo);
    
    return TRUE;
#undef VERIFY
}
int
WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
    WIN_DialogData *dialog;
    int i, x, y;
    UINT_PTR which;
    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
    HFONT DialogFont;
    SIZE Size;
    RECT TextSize;
    wchar_t* wmessage;
    TEXTMETRIC TM;


    const int ButtonWidth = 88;
    const int ButtonHeight = 26;
    const int TextMargin = 16;
    const int ButtonMargin = 12;


    /* Jan 25th, 2013 - [email protected]
     *
     *
     * I've tried to make this more reasonable, but I've run in to a lot
     * of nonsense.
     *
     * The original issue is the code was written in pixels and not
     * dialog units (DLUs). All DialogBox functions use DLUs, which
     * vary based on the selected font (yay).
     *
     * According to MSDN, the most reliable way to convert is via
     * MapDialogUnits, which requires an HWND, which we don't have
     * at time of template creation.
     *
     * We do however have:
     *  The system font (DLU width 8 for me)
     *  The font we select for the dialog (DLU width 6 for me)
     *
     * Based on experimentation, *neither* of these return the value
     * actually used. Stepping in to MapDialogUnits(), the conversion
     * is fairly clear, and uses 7 for me.
     *
     * As a result, some of this is hacky to ensure the sizing is
     * somewhat correct.
     *
     * Honestly, a long term solution is to use CreateWindow, not CreateDialog.
     *

     *
     * In order to get text dimensions we need to have a DC with the desired font.
     * I'm assuming a dialog box in SDL is rare enough we can to the create.
     */
    HDC FontDC = CreateCompatibleDC(0);

    {
        /* Create a duplicate of the font used in system message boxes. */
        LOGFONT lf;
        NONCLIENTMETRICS NCM;
        NCM.cbSize = sizeof(NCM);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
        lf = NCM.lfMessageFont;
        DialogFont = CreateFontIndirect(&lf);
    }

    /* Select the font in to our DC */
    SelectObject(FontDC, DialogFont);

    {
        /* Get the metrics to try and figure our DLU conversion. */
        GetTextMetrics(FontDC, &TM);
        s_BaseUnitsX = TM.tmAveCharWidth + 1;
        s_BaseUnitsY = TM.tmHeight;
    }

    /* Measure the *pixel* size of the string. */
    wmessage = WIN_UTF8ToString(messageboxdata->message);
    SDL_zero(TextSize);
    Size.cx = DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT);

    /* Add some padding for hangs, etc. */
    TextSize.right += 2;
    TextSize.bottom += 2;

    /* Done with the DC, and the string */
    DeleteDC(FontDC);
    SDL_free(wmessage);

    /* Increase the size of the dialog by some border spacing around the text. */
    Size.cx = TextSize.right - TextSize.left;
    Size.cy = TextSize.bottom - TextSize.top;
    Size.cx += TextMargin * 2;
    Size.cy += TextMargin * 2;

    /* Ensure the size is wide enough for all of the buttons. */
    if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
        Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;

    /* Add vertical space for the buttons and border. */
    Size.cy += ButtonHeight + TextMargin;

    dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->title);
    if (!dialog) {
        return -1;
    }

    if (!AddDialogStatic(dialog, TextMargin, TextMargin, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
        FreeDialogData(dialog);
        return -1;
    }

    /* Align the buttons to the right/bottom. */
    x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
    y = Size.cy - ButtonHeight - ButtonMargin;
    for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
        SDL_bool isDefault;

        if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
            isDefault = SDL_TRUE;
        } else {
            isDefault = SDL_FALSE;
        }
        if (!AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttons[i].text, i, isDefault)) {
            FreeDialogData(dialog);
            return -1;
        }
        x += ButtonWidth + ButtonMargin;
    }

    /* FIXME: If we have a parent window, get the Instance and HWND for them */
    which = DialogBoxIndirect(NULL, (DLGTEMPLATE*)dialog->lpDialog, NULL, (DLGPROC)MessageBoxDialogProc);
    *buttonid = buttons[which].buttonid;

    FreeDialogData(dialog);
    return 0;
}
Example #25
0
LRESULT WINAPI 
LVEdit_WndProc
(
	HWND				hWnd,
    UINT				uMessage,
    WPARAM				wParam,
    LPARAM				lParam
)
{
    LRESULT             lResult             = 0;
    BOOL                bCallOrigWndProc    = FALSE;
    static int          tmHeight            = 0;
	switch (uMessage)
	{
        case WM_ERASEBKGND:
            {
                RECT    rc;
                HDC     hdc = ( HDC )wParam;
                GetClientRect ( hWnd, &rc );
                Rectangle ( hdc, rc.left, rc.top, rc.right, rc.bottom );
                return -1;
            }
        case WM_GETDLGCODE:
			return ( LRESULT )DLGC_WANTARROWS | DLGC_WANTALLKEYS;
        case WM_SETFONT:
            {
                HDC     hdc;
                TEXTMETRIC tm;
                CallWindowProc( ( FARPROC )GetClassLong ( hWnd, GCL_WNDPROC ),
                                   hWnd, uMessage, wParam, lParam );
                hdc = GetDC ( hWnd );
                GetTextMetrics ( hdc, &tm );
                tmHeight = tm.tmHeight;
                ReleaseDC ( hWnd, hdc );
                break;
            }
	case WM_KEYDOWN:
            CallWindowProc( ( FARPROC )GetClassLong ( hWnd, GCL_WNDPROC ),
                                   hWnd, uMessage, wParam, lParam );
            if ( ( int )wParam == VK_ESCAPE || ( int )wParam == VK_RETURN )
                SendMessage ( GetParent ( hWnd ), uMessage, wParam, lParam );
            else
            {
                RECT    rect;                      
                char    szText[MAXSTRING];
                UINT    edtStyle;
                RECT    rcText;
                HDC     hDC = GetDC ( hWnd );
#if 0
                RECT    rcDad;                      
                SIZE    size;
                HWND    hwParent = GetParent ( hWnd );
                GetWindowRect ( hWnd, &rect );
                MapWindowPoints ( ( HWND )NULL, hwParent, ( LPPOINT )&rect.left, 2 ); 
                GetClientRect ( hwParent, &rcDad );
                GetWindowText ( hWnd, szText, MAXSTRING );
                GetTextExtentPoint32 ( hDC, szText, lstrlen ( szText ), &size ); 
#else
                GetWindowText ( hWnd, szText, MAXSTRING );
                GetWindowRect ( hWnd, &rect );
                SetRect ( &rcText, 0, 0, rect.right - rect.left, rect.bottom - rect.top );
#endif
                edtStyle = GetWindowLong ( hWnd, GWL_STYLE );
                if ( edtStyle & ES_MULTILINE )
                {
                    DrawText ( hDC, szText, lstrlen ( szText ),&rcText, 
                               DT_CALCRECT | DT_WORDBREAK );
#if 1
                    if ( rcText.bottom > rect.bottom - rect.top )
                        SetWindowPos ( hWnd, ( HWND )NULL, 0, 0, 
                                   rect.right-rect.left, rcText.bottom,
                                   SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER );
#endif
                }
                else
                {
                    DrawText ( hDC, szText, lstrlen ( szText ),&rcText, 
                               DT_CALCRECT | DT_LEFT );
                    if ( rcText.right - rcText.left < 50 )
                        rcText.right = rcText.left + 50;
#if 1
                    SetWindowPos ( hWnd, ( HWND )NULL, 0, 0, 
                                   rcText.right - rcText.left + 5, 
                                   rcText.bottom,
                                   SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER );
#endif
                }
                ReleaseDC ( hWnd, hDC );
            }

            break;

        default:
			return CallWindowProc( ( FARPROC )GetClassLong ( hWnd, GCL_WNDPROC ),
                                   hWnd, uMessage, wParam, lParam );
	}
    
	if ( bCallOrigWndProc )
        lResult = CallWindowProc( ( FARPROC )GetClassLong ( hWnd, GCL_WNDPROC ),
                                   hWnd, uMessage, wParam, lParam );
    return lResult;
}
Example #26
0
File: mhmenu.c Project: yzh/yzhack
void mswin_menu_window_size (HWND hWnd, LPSIZE sz)
{
    TEXTMETRIC tm;
	HWND control;
	HGDIOBJ saveFont;
	HDC hdc;
	PNHMenuWindow data;
	int i;
	RECT rt, wrt;
	int extra_cx;

	GetClientRect(hWnd, &rt);
	sz->cx = rt.right - rt.left;
	sz->cy = rt.bottom - rt.top;

	GetWindowRect(hWnd, &wrt);
	extra_cx = (wrt.right-wrt.left) - sz->cx;

	data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);
	if(data) {
		control = GetMenuControl(hWnd);
		hdc = GetDC(control);

		if( data->type==MENU_TYPE_MENU ) {
			/* Calculate the width of the list box. */
			saveFont = SelectObject(hdc, mswin_get_font(NHW_MENU, ATR_NONE, hdc, FALSE));
			GetTextMetrics(hdc, &tm);
			for(i=0; i<data->menu.size; i++ ) {
				LONG menuitemwidth = 0;
				int column;
				char *p, *p1;

				p1 = data->menu.items[i].str;
				p = strchr(data->menu.items[i].str, '\t');
				column = 0;
				for (;;) {
					TCHAR wbuf[BUFSZ];
					RECT tabRect;
					SetRect ( &tabRect, 0, 0, 1, 1 );
					if (p != NULL) *p = '\0'; /* for time being, view tab field as zstring */
					DrawText(hdc,
						NH_A2W(p1, wbuf, BUFSZ),
/*JP
						strlen(p1),
*/
						-1,
						&tabRect,
						DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE
					);
					/* it probably isn't necessary to recompute the tab width now, but do so
					 * just in case, honoring the previously computed value
					 */
					menuitemwidth += max(data->menu.tab_stop_size[column],
					    tabRect.right - tabRect.left);
					if (p != NULL) *p = '\t';
					else /* last string so, */ break;
					/* add the separation only when not the last item */
					/* in the last item, we break out of the loop, in the statement just above */
					menuitemwidth += TAB_SEPARATION;
					++column;
					p1 = p + 1;
					p = strchr(p1, '\t');
				}

				sz->cx = max(sz->cx, 
					(LONG)(2*TILE_X + menuitemwidth + tm.tmAveCharWidth*12 + tm.tmOverhang));
			}
			SelectObject(hdc, saveFont);
		} else {
			/* do not change size for text output - the text will be formatted to
			   fit any window */
		}
		sz->cx += extra_cx;

		ReleaseDC(control, hdc);
	}
}
Example #27
0
void
text_copy_to_clipboard(TW *tw)
{
    int size, count;
    HGLOBAL hGMem;
#ifdef WINDOWS_NO_UNICODE
    LPSTR cbuf, cp;
    HDC hdc;
    TEXTMETRIC tm;
#else
    LPWSTR cbuf, cp;
#endif
    UINT type;
    int i;

    size = tw->ScreenSize.y * (tw->ScreenSize.x + 2) + 1;
    size *= CHARSIZE;
    hGMem = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)size);
#ifdef WINDOWS_NO_UNICODE
    cbuf = cp = (LPSTR)GlobalLock(hGMem);
#else
    cbuf = cp = (LPWSTR)GlobalLock(hGMem);
#endif
    if (cp == NULL)
        return;

    for (i=0; i<tw->ScreenSize.y; i++) {
        count = tw->ScreenSize.x;
        memcpy(cp, tw->ScreenBuffer + tw->ScreenSize.x*i, count*CHARSIZE);
        /* remove trailing spaces */
        for (count=count-1; count>=0; count--) {
                if (cp[count]!=' ')
                        break;
                cp[count] = '\0';
        }
        cp[++count] = '\r';
        cp[++count] = '\n';
        cp[++count] = '\0';
        cp += count;
    }
    /* Now remove completely empty trailing lines */
    while (cp >= cbuf+4) {
        if ((cp[-3] != '\n') || (cp[-4] != '\r'))
            break;
        cp -= 2;
        *cp = '\0';
    }
#ifdef WINDOWS_NO_UNICODE
    size = strlen(cbuf) + 1;
#else
    size = CHARSIZE*(wcslen(cbuf) + 1);
#endif
    GlobalUnlock(hGMem);
    hGMem = GlobalReAlloc(hGMem, (DWORD)size, GHND | GMEM_SHARE);
#ifdef WINDOWS_NO_UNICODE
    /* find out what type to put into clipboard */
    hdc = GetDC(tw->hwnd);
    SelectFont(hdc, tw->hfont);
    GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
    if (tm.tmCharSet == OEM_CHARSET)
        type = CF_OEMTEXT;
    else
        type = CF_TEXT;
    ReleaseDC(tw->hwnd, hdc);
#else
    type = CF_UNICODETEXT;
#endif
    /* give buffer to clipboard */
    OpenClipboard(tw->hwnd);
    EmptyClipboard();
    SetClipboardData(type, hGMem);
    CloseClipboard();
}
Example #28
0
File: mhmenu.c Project: yzh/yzhack
LRESULT onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    LPDRAWITEMSTRUCT lpdis; 
	PNHMenuItem item;
	PNHMenuWindow data;
    TEXTMETRIC tm;
	HGDIOBJ saveFont;
	HDC tileDC;
	short ntile;
	int t_x, t_y;
	int x, y;
	TCHAR wbuf[BUFSZ];
	RECT drawRect;
	COLORREF OldBg, OldFg, NewBg;
	char *p, *p1;
	int column;

	lpdis = (LPDRAWITEMSTRUCT) lParam; 

    /* If there are no list box items, skip this message. */
    if (lpdis->itemID == -1) return FALSE;

	data = (PNHMenuWindow)GetWindowLong(hWnd, GWL_USERDATA);

    item = &data->menu.items[lpdis->itemID];

	tileDC = CreateCompatibleDC(lpdis->hDC);
	saveFont = SelectObject(lpdis->hDC, mswin_get_font(NHW_MENU, item->attr, lpdis->hDC, FALSE));
	NewBg = mswin_get_color(NHW_MENU, MSWIN_COLOR_BG);
	OldBg = SetBkColor(lpdis->hDC, NewBg);
	OldFg = SetTextColor(lpdis->hDC, mswin_get_color(NHW_MENU, MSWIN_COLOR_FG)); 

    GetTextMetrics(lpdis->hDC, &tm);

	x = lpdis->rcItem.left + 1;

	/* print check mark if it is a "selectable" menu */
	if( data->how!=PICK_NONE ) {
		if( NHMENU_IS_SELECTABLE(*item) ) {
			HGDIOBJ saveBrush;
			HBRUSH	hbrCheckMark;
			char buf[2];

			switch(item->count) {
			case -1: hbrCheckMark = CreatePatternBrush(data->bmpChecked); break;
			case 0: hbrCheckMark = CreatePatternBrush(data->bmpNotChecked); break;
			default: hbrCheckMark = CreatePatternBrush(data->bmpCheckedCount); break;
			}

			y = (lpdis->rcItem.bottom + lpdis->rcItem.top - TILE_Y) / 2; 
			SetBrushOrgEx(lpdis->hDC, x, y, NULL);
			saveBrush = SelectObject(lpdis->hDC, hbrCheckMark);
			PatBlt(lpdis->hDC, x, y, TILE_X, TILE_Y, PATCOPY);
			SelectObject(lpdis->hDC, saveBrush);
			DeleteObject(hbrCheckMark);

			x += TILE_X + 5;

			if(item->accelerator!=0) {
				buf[0] = item->accelerator;
				buf[1] = '\x0';

				SetRect( &drawRect, x, lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom );
/*JP
				DrawText(lpdis->hDC, NH_A2W(buf, wbuf, 2), 1, &drawRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
*/
				DrawText(lpdis->hDC, NH_A2W(buf, wbuf, 2), -1, &drawRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
			}
			x += tm.tmAveCharWidth + tm.tmOverhang + 5;
		} else {
			x += TILE_X + tm.tmAveCharWidth + tm.tmOverhang + 10;
		}
	}

	/* print glyph if present */
	if( item->glyph != NO_GLYPH ) {
		HGDIOBJ saveBmp;

		saveBmp = SelectObject(tileDC, GetNHApp()->bmpTiles);				
		ntile = glyph2tile[ item->glyph ];
		t_x = (ntile % TILES_PER_LINE)*TILE_X;
		t_y = (ntile / TILES_PER_LINE)*TILE_Y;

		y = (lpdis->rcItem.bottom + lpdis->rcItem.top - TILE_Y) / 2; 

		nhapply_image_transparent(
			lpdis->hDC, x, y, TILE_X, TILE_Y, 
			tileDC, t_x, t_y, TILE_X, TILE_Y, TILE_BK_COLOR );
		SelectObject(tileDC, saveBmp);
	}

	x += TILE_X + 5;

	/* draw item text */
	if( item->has_tab ) {
		p1 = item->str;
		p = strchr(item->str, '\t');
		column = 0;
		SetRect( &drawRect, x, lpdis->rcItem.top, min(x + data->menu.tab_stop_size[0], lpdis->rcItem.right),
			lpdis->rcItem.bottom );
		for (;;) {
			TCHAR wbuf[BUFSZ];
			if (p != NULL) *p = '\0'; /* for time being, view tab field as zstring */
			DrawText(lpdis->hDC,
				NH_A2W(p1, wbuf, BUFSZ),
/*JP
				strlen(p1),
*/
				-1,
				&drawRect,
				DT_LEFT | DT_VCENTER | DT_SINGLELINE
			);
			if (p != NULL) *p = '\t';
			else /* last string so, */ break;

			p1 = p + 1;
			p = strchr(p1, '\t');
			drawRect.left = drawRect.right + TAB_SEPARATION;
			++column;
			drawRect.right = min (drawRect.left + data->menu.tab_stop_size[column], lpdis->rcItem.right);
		}
	} else {
		TCHAR wbuf[BUFSZ];
		SetRect( &drawRect, x, lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom);
		DrawText(lpdis->hDC,
			NH_A2W(item->str, wbuf, BUFSZ),
/*JP
			strlen(item->str),
*/
			-1,
			&drawRect,
			DT_LEFT | DT_VCENTER | DT_SINGLELINE
		);
	}

	/* draw focused item */
	if( item->has_focus ) {
		RECT client_rt;
		HBRUSH bkBrush;

		GetClientRect(lpdis->hwndItem, &client_rt);
		if( NHMENU_IS_SELECTABLE(*item) && 
			data->menu.items[lpdis->itemID].count>0 &&
			item->glyph != NO_GLYPH ) {
			if( data->menu.items[lpdis->itemID].count==-1 ) {
				_stprintf(wbuf, TEXT("Count: All") );
			} else {
				_stprintf(wbuf, TEXT("Count: %d"), data->menu.items[lpdis->itemID].count );
			}

			SelectObject(lpdis->hDC, mswin_get_font(NHW_MENU, ATR_BLINK, lpdis->hDC, FALSE));

			/* calculate text rectangle */
			SetRect( &drawRect, client_rt.left, lpdis->rcItem.top, client_rt.right, lpdis->rcItem.bottom );
/*JP
			DrawText(lpdis->hDC, wbuf, _tcslen(wbuf), &drawRect, 
*/
			DrawText(lpdis->hDC, wbuf, -1, &drawRect, 
					 DT_CALCRECT | DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX );
			
			/* erase text rectangle */
			drawRect.left = max(client_rt.left+1, client_rt.right - (drawRect.right - drawRect.left) - 10);
			drawRect.right = client_rt.right-1;
			drawRect.top = lpdis->rcItem.top;
			drawRect.bottom = lpdis->rcItem.bottom;
			bkBrush = CreateSolidBrush( GetBkColor(lpdis->hDC) );
			FillRect(lpdis->hDC, &drawRect, bkBrush );
			DeleteObject( bkBrush );

			/* draw text */
/*JP
			DrawText(lpdis->hDC, wbuf, _tcslen(wbuf), &drawRect, 
*/
			DrawText(lpdis->hDC, wbuf, -1, &drawRect, 
					 DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX );
		}

		/* draw focus rect */
		SetRect( &drawRect, client_rt.left, lpdis->rcItem.top, client_rt.right, lpdis->rcItem.bottom );
		DrawFocusRect(lpdis->hDC, &drawRect);
	}

	SetTextColor (lpdis->hDC, OldFg);
	SetBkColor (lpdis->hDC, OldBg);
	SelectObject(lpdis->hDC, saveFont);
	DeleteDC(tileDC);
	return TRUE;
}
Example #29
0
RenderQueue* BREW::CreateSpinButtonDrawable( SharedPtr<const SpinButton> spinbutton ) const {
	sf::Color border_color( GetProperty<sf::Color>( "BorderColor", spinbutton ) );
	sf::Color background_color( GetProperty<sf::Color>( "BackgroundColor", spinbutton ) );
	sf::Color text_color( GetProperty<sf::Color>( "Color", spinbutton ) );
	sf::Color cursor_color( GetProperty<sf::Color>( "Color", spinbutton ) );
	float text_padding( GetProperty<float>( "Padding", spinbutton ) );
	float cursor_thickness( GetProperty<float>( "Thickness", spinbutton ) );
	float border_width( GetProperty<float>( "BorderWidth", spinbutton ) );
	int border_color_shift( GetProperty<int>( "BorderColorShift", spinbutton ) );
	const sf::Font& font( *GetResourceManager().GetFont( GetProperty<std::string>( "FontName", spinbutton ) ) );
	const unsigned int& font_size( GetProperty<unsigned int>( "FontSize", spinbutton ) );
	float stepper_aspect_ratio( GetProperty<float>( "StepperAspectRatio", spinbutton ) );
	sf::Color stepper_color( GetProperty<sf::Color>( "StepperBackgroundColor", spinbutton ) );
	sf::Color stepper_border_color( GetProperty<sf::Color>( "BorderColor", spinbutton ) );
	sf::Color stepper_arrow_color( GetProperty<sf::Color>( "StepperArrowColor", spinbutton ) );

	RenderQueue* queue( new RenderQueue );

	// Pane.
	queue->Add(
		Renderer::Get().CreatePane(
			sf::Vector2f( 0.f, 0.f ),
			sf::Vector2f( spinbutton->GetAllocation().width, spinbutton->GetAllocation().height ),
			border_width,
			background_color,
			border_color,
			-border_color_shift
		)
	);

	float button_width = ( spinbutton->GetAllocation().height / 2.f ) * stepper_aspect_ratio;

	// Up Stepper.
	queue->Add(
		Renderer::Get().CreatePane(
			sf::Vector2f( spinbutton->GetAllocation().width - button_width - border_width, border_width ),
			sf::Vector2f( button_width, spinbutton->GetAllocation().height / 2.f - border_width ),
			border_width,
			stepper_color,
			stepper_border_color,
			spinbutton->IsIncreaseStepperPressed() ? -border_color_shift : border_color_shift
		)
	);

	// Up Stepper Triangle.
	queue->Add(
		Renderer::Get().CreateTriangle(
			sf::Vector2f( spinbutton->GetAllocation().width - button_width / 2.f - border_width, ( spinbutton->IsIncreaseStepperPressed() ? 1.f : 0.f ) + border_width + spinbutton->GetAllocation().height / 6.f ),
			sf::Vector2f( spinbutton->GetAllocation().width - button_width / 4.f * 3.f - border_width, ( spinbutton->IsIncreaseStepperPressed() ? 1.f : 0.f ) + border_width + spinbutton->GetAllocation().height / 3.f ),
			sf::Vector2f( spinbutton->GetAllocation().width - button_width / 4.f - border_width, ( spinbutton->IsIncreaseStepperPressed() ? 1.f : 0.f ) + border_width + spinbutton->GetAllocation().height / 3.f ),
			stepper_arrow_color
		)
	);

	// Down Stepper.
	queue->Add(
		Renderer::Get().CreatePane(
			sf::Vector2f( spinbutton->GetAllocation().width - button_width - border_width, spinbutton->GetAllocation().height / 2.f ),
			sf::Vector2f( button_width, spinbutton->GetAllocation().height / 2.f - border_width ),
			border_width,
			stepper_color,
			stepper_border_color,
			spinbutton->IsDecreaseStepperPressed() ? -border_color_shift : border_color_shift
		)
	);

	// Down Stepper Triangle.
	queue->Add(
		Renderer::Get().CreateTriangle(
			sf::Vector2f( spinbutton->GetAllocation().width - button_width / 2.f - border_width, ( spinbutton->IsDecreaseStepperPressed() ? 1.f : 0.f ) + spinbutton->GetAllocation().height - border_width - spinbutton->GetAllocation().height / 6.f ),
			sf::Vector2f( spinbutton->GetAllocation().width - button_width / 4.f - border_width, ( spinbutton->IsDecreaseStepperPressed() ? 1.f : 0.f ) + spinbutton->GetAllocation().height - border_width - spinbutton->GetAllocation().height / 3.f ),
			sf::Vector2f( spinbutton->GetAllocation().width - button_width / 4.f * 3.f - border_width, ( spinbutton->IsDecreaseStepperPressed() ? 1.f : 0.f ) + spinbutton->GetAllocation().height - border_width - spinbutton->GetAllocation().height / 3.f ),
			stepper_arrow_color
		)
	);

	float line_height = GetFontLineHeight( font, font_size );
	sf::Text vis_label( spinbutton->GetVisibleText(), font, font_size );
	vis_label.setColor( text_color );
	vis_label.setPosition( text_padding, spinbutton->GetAllocation().height / 2.f - line_height / 2.f );

	queue->Add( Renderer::Get().CreateText( vis_label ) );

	// Draw cursor if spinbutton is active and cursor is visible.
	if( spinbutton->HasFocus() && spinbutton->IsCursorVisible() ) {
		sf::String cursor_string( spinbutton->GetVisibleText() );
		if( spinbutton->GetCursorPosition() - spinbutton->GetVisibleOffset() < cursor_string.getSize() ) {
			cursor_string.erase( spinbutton->GetCursorPosition() - spinbutton->GetVisibleOffset(), cursor_string.getSize() );
		}

		// Get metrics.
		sf::Vector2f metrics( GetTextMetrics( cursor_string, font, font_size ) );

		queue->Add(
			Renderer::Get().CreateRect(
				sf::FloatRect(
					metrics.x + text_padding,
					spinbutton->GetAllocation().height / 2.f - line_height / 2.f,
					cursor_thickness,
					line_height
				),
				cursor_color
			)
		);
	}

	return queue;
}
       // Draw text within margins, left-justified, with word-wrap.
       // Draw to <hdc> context, so it supports display and bitmaps   
       // (bitmap must already be created and selected into context).
       // Draw boxes for each word on EyeLink tracker display if <dotrack> set
       // Use font selected with get_new_font(), and draws it in <color>
       // RECT <margins> sets margins, and <lspace> sets pixels between lines
void draw_text_box(HDC hdc, char *txt, COLORREF color, RECT margins, int lspace, int dotrack)
{
  short x, y;              // drawing position
  char *sword, *eword;     // word start, end pointer
  int swx, ewx;            // word start, end position
  char *sispace, *c;       // text pointers
  int height;              // height of characters
  SIZE size;
  TEXTMETRIC tm;

  if(dotrack) eyecmd_printf("clear_screen 0");	// clear eye tracker display

  SetBkMode(hdc, TRANSPARENT);        // set text color
  SetTextColor(hdc, color);
  SelectObject(hdc, current_font);    // Select cached font into context

  GetTextMetrics(hdc, &tm);           // Get height of characters
  height = tm.tmHeight;
  SetTextJustification(hdc, 0, 0) ;   // set normal text spacing
  SetTextAlign(hdc, TA_LEFT | TA_TOP);

  x = (short)margins.left;                   // initial drawing position
  y = (short)margins.top;  
  c = txt;                            // initial text to scan

  while(*c)   // loop through lines of text
    {
nextword:                 // START NEW WORD:
      sispace = c;            // scan over any leading spaces
      while(*c==' ') c++;
      if(c!=sispace)          // advance over the spaces (if any)
        {
          GetTextExtentPoint32(hdc, sispace, c-sispace, &size);                    
          x += (short)size.cx;
        }
      if(*c==0) break;    // handle end-of-text 
      if(*c=='\n')        // handle end-of-line before word
        {
          c++;            // skip over end-of-line character
nextline:                        // START NEW LINE:
          x = (short)margins.left;                      // return to start of line
          y += lspace;                           // top of new  line
          if(y+height > margins.bottom) break;  // stop if it would go outside margins
          goto nextword;                         // continue to print
        }
      swx = x;            // continue in current line: 
      sword = c;                                  // record start of this word
      while(*c && !isspace(*c) && *c!='\n') c++;  // scan till end of word
      if(sword==c) goto nextword;                 // no word: continue by skipping spaces
      eword = c;                                  // record end of word
      GetTextExtentPoint32(hdc, sword, eword-sword, &size);   // width of word                 
      ewx = size.cx + swx;                        // position of end of word
      if(ewx > margins.right)    // would it extend past right margin?
        {
          c = sword;                   // restore text pointer
          goto nextline;               // start a new line with current word
        }
      TextOut(hdc, x, y, sword, eword-sword);      // Print the word
      if(dotrack)                                  // draw box on EyeLink display
          eyecmd_printf("draw_box %d %d %d %d 15", swx, y, ewx, y+height);
      x = ewx;                                     // update current printing location
    }

  GdiFlush();     // ADDED for Wimdows 2000/XP: Forces drawing to be immediate      

  SelectObject(hdc, GetStockObject(SYSTEM_FONT));  // deselect the font
}