Что такое код getviewportorg

Содержание

Что такое код getviewportorg

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Т.е. режим отображения задается в MM_TEXT, хочу получить эти же координаты, но измерянные в MM_HIMETRIC;
вот что выводит:
MM_TEXT: cx = 15840 (11″ * 1440 = 15840 точек), т.е. все верно и все работает
MM_HIMETRIC: cx = 134112 — вот здесь уже не понятно, откуда в принципе взялась эта цифра.

Не понятно, как получить из координаты MM_TEXТ координату MM_HIMETRIC.
Вобщем-то, мне нужно преобразование «наборот», т.е. из химетрика в текст. Но хотя бы с этим разобраться.
Может, кто сталкивался с подобным?

Простые типы 7 страница

INCLUDED.)
«define AFX_MAINFRM_H__AF072C87_900A_11DO_8860_444553540000__INCLUDED_

Bit _MSC_VER >= 1000
#pragma once
tfendif // _MSC_VER >= 1000
class CMainFrame : public CFrameWnd
<
protected: // создание только при сериализации
CMainFrameO;
DECLARE_DYNCREATE(CMainFrame)

// Атрибуты
public:
// Операции
public:
// Переопределения
// Переопределения виртуальных функций, сгенерированные ClassWizard
//( Virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//>>AFX_VIRTUAL
// Реализация
public:
virtual «CmainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // Внутренние управляющие объекты
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;

// Сгенерированные функции схемы сообщений
protected:
// <afxjnsg int OnCreate(LPCREATESTRUCT IpCreateStruct);
// ВНИМАНИЕ — здесь ClassWizard вставляет и удаляет функции класса.
// НЕ ИЗМЕНЯЙТЕ содержимое этих частей сгенерированного кода!
//>>AFX_MSG
DECLARE_MESSAGE_MAP()
>;
/////////////////////////////////////////////////////////////////////////
//<>
// Microsoft Visual C++ вставляет дополнительные объявления
// перед предшествующей строкой.

#endif
//
!defined(AFX_MAINFRM_H__8A1BC189_B34B_11D1_887F_D42B07C10710__INCLUDED_)
// MainFrm. cpp : реализация класса CMainFrame
//
#include «stdafx.h»
#include «welcome, h»
#include «MainFrm.h»
#ifdef _DEBUG

#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////У////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame. CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame. CFrameWnd)

// <// ВНИМАНИЕ — здесь ClassWizard добавляет и удаляет макросы схемы.
// НЕ ИЗМЕНЯЙТЕ содержимое этих частей сгенерированного кода!
ON_WM_CREATE()
//>>AFX_MSG_MAP
END_MESSAGE_MAP()
static DINT indicators[] =
<
ID_SEPARATOR, // индикаторы строки состояния
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
>;
/////////////////////////////////////////////////////////////////////////•
// Создание/уничтожение CMainFrame
CMainFrame::CMainFrame()

<
// TODO: добавьте код для инициализации переменных класса
>
CMainFrame::

CMainFrame()
<
>
int CMainFrame::OnCreate(LPCREATESTRUCT IpCreateStruct)
<
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER |
CBRS_TOOLT1PS | CBRS_FLYBY |
CBRS|SIZE_DYNAMIC) | |
! m_wndToolBar. LoadToolBaг(IDR_MAINFRAME))
<
TRACEO («Failed to create toolbar\n»);
return -1; // неудачная попытка создания

>
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.Setlndicatorstindicators,
sizeof(indicators)/sizeof(UINT)))
<
TRACEO(«Failed to create status bar\n»);
return -1; // неудачная попытка создания
>
// TODO: Удалите следующие три строки, если вам не нужна
// закрепляемая панель инструментов
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableOocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

// TODO: Измените класс окна или его стили, редактируя
// содержимое CREATESTRUCT cs
return CFrameWnd::PreCreateWindow(cs);
/////////////////////////////////////////////////////////////////////
Диагностика в CMainFrame
#ifdef _DEBUG
void CMainFrame::AssertValid() const <
CFrameWnd::AssertValid();>
void CMainFrame: :Dump(CDumpContext& dc) const
CFrameWnd::Dump(dc);
>
#endif //_DEBUG
///////////////////////////////////////////////////////////////////////
// Обработчики сообщений CMainFrame

Перейдем к объекту вида — он отвечает за отображение данных из документа в
клиентской области окна программы. Большая часть наших действий связана
именно с объектом вида.

9.10.5. Исследуем объект вида
В объекте вида выводится наше сообщение «Добро пожаловать в Visual C++!».
Это происходит в методе OnDraw() файла welcomeView.cpp:
void CWelcomeView: :OnDraw(CDС pDC)
<
CString welcome_string = «Добро пожаловать в Visual C++»;
CWelcomeOoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

pDC->TextOut(0, 0, welcome_string);
>

Этот метод вызывается в ситуации, когда требуется перерисовать клиентскую об-
ласть. На самом деле именно так станут работать все наши программы — они бу-
дут разбиты на множество различных методов, предназначенных для обработки
конкретных сообщений Windows.

9.10.6. Программирование, управляемое событиями

Программы для Windows управляются событиями (event-driven). Это означает,
что они реагируют на действия пользователя, называемые событиями, — щелчки
кнопкой мыши, нажатия клавиш и т. д. При наступлении любого из этих событий
в программе вызывается соответствующий метод. Тем самым удается разбить ее
на небольшие методы, соответствующие различным сообщениям Windows. Напри-
мер, метод OnDraw() вызывается при необходимости перерисовать клиентскую
область — когда окно впервые отображается на экране, когда пользователь пере-
мещает окно, закрывавшее часть нашего окна, или же сворачивает и разворачива-
ет текущее окно.

Вывод сообщения в объекте вида
Что же происходит в методе OnDraw() при выводе текста? Прежде всего мы созда-
ем новый объект welcome_string, принадлежащий классу MFC CString, и заносим
в него текст:
void CwelcomeView::OnDraw(CDC* pDC)
<
CString welcome_string = «Добро пожаловать в Visual C++»;
CWelcomeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(0, 0, welcome_string);
>
Класс CString содержит все операции со строками. Он чрезвычайно полезен и яв-
ляется заметным достижением по сравнению с принятой в языке С интерпрета-
цией строк как символьных массивов.
Класс CString содержит следующие методы:
AllocSysString AnsiToOem Collate
Compare CompareNoCase CString
Empty Find FindOneOf
Format FormatMessage FreeExtra
GetAt GetBuffer GetBufferSetLength
GetLength IsEmpty Left
LoadString LockBuffer MakeLower
MakeReverse MakeUpper Mid
OemToAnsi оператор [] оператор +
оператор += оператор « оператор =
оператор == TextOut(0, 0, welcome_stnng);
>
Класс CDC чрезвычайно важен для нас, поскольку он предназначен для работы с контекстами устройств. Весь графический и текстовый вывод, выполняемый нами
I) Visual C++, будет осуществляться через контексты устройств.

Что такое контекст устройства?
Вы должны хорошо понимать, что такое «контекст устройства». Вообще говоря,
так называется область памяти, используемая в системе Windows для выполнения
графических операций. Графический вывод может выполняться как на экран, так
и на принтер. Объекты класса CDC содержат множество встроенных методов, используемых в процессе рисования в контексте устройства. Все рисование в Windows выполняется через контекст устройства.
Чтобы рисовать в нашем объекте вида, мы получаем контекст устройства, относя-
щийся к нему. Кроме того, можно получить контекст устройства для всего окна,
всего экрана или принтера. Для рисования в контексте устройства используются
перечисленные ниже методы класса CDC; обратите внимание на их количество.
AbortDoc AbortPath AddMetaFileComment
AngleArc Arc ArcTo
Attach BeginPath BitBlt
CDC Chord CloseFigure
CreateCompatibleDC CreateDC CreateIC
DeleteDC DeleteTempMap Detach
DPtoHIMETRIC DPtoLP DrawSdRect
DrawDragRect DrawEdge DrawEscape
DrawFocusRect DrawFrameControl Drawlcon
DrawState DrawText Ellipse
I ndOoc EndPage Endpath
InumObjects Escape ExcludeCllpRect

ExcludellpdateRgn ExtFloodFill ExtTextOut
FillPath FillRect FillRgn .
FillSolidRect FlattenPath FloodFlll

FrameRect FrameRgn FromHandle
GetArcDirection GetAspectRatioFilter GetBkColor
GetBkMode GetBoundsRect GetBrushOrg
GetCharABCWidths GetCharWidth GetClipBox
GetColorAdjustment GetCurrentBitmap GetCurrentBrush
GetCurrentFont GetCurrentPalette GetCurrentPen
GetCurrentPosition GetDeviceCaps GetFontData
GetGlyphOutline GetHalftoneBrush GetKerningPairs
GetMapMode GetMiterLimit GetNearestColor

GetOutlineTextMetrics GetOutputCharWidth GetOutputTabbedTextExtent

GetOutputTextExtent GetOutputTextMetrics GetPath
GetPixel GetPolyFillMode GetROP2
GetSafeHdc GetStretchBltMode GetTabbedTextExtent

GetTextAlign GetTextCharacterExtra GetTextColor

GetTextExtent GetTextFace GetTextMetrics
GetViewportExt GetViewportOrg GetWindow
GetWindowExt GetWindowOrg GrayString
HIMETRICtoDP HIMETRICtoLP IntersectClipRect
InvertRect InvertRgn LineTo
LPtoDP LPtoHIMETRIC MaskBlt
MoveTo OffsetClipRgn OffsetViewpotOrg
OffsetWindowOrg PaintRgn PatBlt
Pie PlayMetafile PlgBlt
PolyBezier PolyBezierTo PolyDraw
Polygon Polyline PolylineTo

PolyPolygon PolyPolyline PtVisible
QueryAbort ReallzePalette Rectangle
RectVisible ReleaseAttrlbDC ReleaseOutputDC
ResetDC RestoreDC RoundRect
SaveDC ScaleViewportExt ScaleWindowExt
ScrollDC SelectClipPath SelectClipRgn
SelectObject SelectPalette SelectStockObject
SetAbortProc SetArcDirection SetAttrlbDC
SetBkColor SetBkMode SetBoundsRect
SetBrushOrg SetColorAdjustment SetMapMode

SolMapperFlags SetMiterLimit SetOutputDC

SetPixel SetPixclV SetPolyFillMode
SetROP2 SetStretchBltMode SetTextAlign

SetTextCharacterExtra SetTextColor SetTextJustification

SotViewportExt SetViewportOrg SetWindowExt
SotWindowOrg StartDoc StartPage
MretchBlt StrokeAndFillPath StrokePath
labbedTextOut TextOut UpdateColors
WidenPath
Внашем случае для вывода в объекте вида (соответствующего клиентской облас-
ти окна) был использован метод TextOut класса CDC. Методу OnDraw() передается
указатель рDС, ссылающийся на контекст устройства для нашего вида. Чтобы вы-
нести текст welcome_string в клиентской области, достаточно выполнить следую-
щую строку:
pDC->TextOut(0, 0, welcome_string);
Методу TextOut () передаются координаты левого верхнего угла той области окна,
где должна располагаться наша строка. В нашем случае текст выводится с точки
(О, 0) — левого верхнего угла клиентской области. Затем метод получает саму стро-
ку, welcome_string.
Итак, выполнение этой строки программы приводит к тому, что наша строка вы-
водится на экран. Так данные программы отображаются в объекте вида.
В последующих уроках мы узнаем об объекте вида намного больше, потому что
именно с ним будет связана основная часть программирования. Исходный текст
объекта вида находится в файлах welcomeView.h/welcomeView.cpp.
welcomeView.h и welcomeView.cpp
// welcomeView. h : интерфейс класса CWelcomeView
//

////////////////////////////////////////////////////////////////////////
#if !defined(AFXjAlELCOMEVIEW_H__AF072C8B_900A_11DO_8860_444553540000__
INCLUDEDJ
#define AFX_WELCOMEVIEW_H__AF072C8B_900A_11DO_8860_444553540000__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class CWelcomeView : public CView
<
protected: // создание только при сериализации
CWelcomeViewO;
DECLARE_DYNCREATE(CWelcomeView)
// Атрибуты
public:
CWelcomeDoc* GetDocumentO;

// Операции
public:
// Переопределения
// Переопределения виртуальных функций, сгенерированные ClassWizard
// <public:
virtual void OnDraw(CDC* pDC); // переопределяется для рисования
// в текущем виде
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* plnfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintlnfo* plnfo);
virtual void OnEndPrinting(CDO pDC, CPrintlnfo* plnfo);
//>>AFX_VIRTUAL
// Реализация
public:
virtual «CWelcomeViewO;
#ifdef _DEBUG
virtual void AssertValidQ const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Сгенерированные функции схемы сообщений
protected:
// <// ВНИМАНИЕ — здесь ClassWizard вставляет и удаляет функции класса.
// НЕ ИЗМЕНЯЙТЕ содержимое этих блоков сгенерированного кода!
//>>AFX_MSG
DECLARE_MESSAGE_MAP()
>;

#ifndef _DEBUG // отладочная версия — в welcomeView.cpp
inline CWelcomeDoc* CWelcomeView::GetDocument()
< return (CWelcomeDoc*)m_pDocument; >
#endif
////////////////////////////////////////////////////////////////////////
//<>
// Microsoft Visual C++ вставляет дополнительные объявления
// перед предшествующей строкой.
#endif
// !defined(AFX_WELCOMEVIEW_H__AF072C8B_900A_
// 11DO_8860_444553540000__INCLUDED_)
// welcomeView.cpp : реализация класса CWelcomeView
//
#include «stdafx.h»
#include «welcome.h»
#include «welcomeDoc. h»
#include «welcomeView. h»
#ifdef _DEBUG
tfdefine new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////////
// CWelcomeView
IMPLEMENT_DYNCREATE(CWelcomeView, CView)
BEGIN_MESSAGE_MAP(CWelcomeView, CView)
// <// ВНИМАНИЕ — здесь ClassWizard добавляет и удаляет макросы схемы.
// НЕ ИЗМЕНЯЙТЕ содержимое этих частей сгенерированного кода!
//>>AFX_MSG_MAP
// Стандартные команды печати
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView: :OnFilePnntPreview)
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////
// Создание/уничтожение CWelcomeView
CWelcomeView::CWelcomeView()
<
// TODO: добавьте код конструктора
>
CWelcomeView::»CWelcomeView()
<
>
BOOL CWelcomeView::PreCreateWindow(CREATESTRUCT& cs)
<
// TODO: Измените класс окна или его стили, редактируя
// содержимое CREATESTRUCT cs
return CView::PreCreateWindow(cs);

II Рисование в CWelcomeView
void CWelcomeView::OnDraw(CDC* pDC)
<
CString welcome_string = «Добро пожаловать в Visual C++»;
CWelcomeDoc* pDoc = GetDocumentO;
ASSERT_VALID(pDoc);
pDC->TextOut(0, 0, welcome_string.);
// T0DO: добавьте код для отображений данных
>
//////////////////////////////////////////У//////////////////////////////
// Печать в CWelcomeView
BOOL CWelcomeView::OnPreparePrinting(CPrintInfo* plnfo)
<
// Стандартная подготовка
return DoPreparePrinting(pInfo);
>
void CWelcomeView: :OnBeginPrinting(CDC* /*pDO/, CPrintlnfo* /*plnfo*/)
<
// TODO: добавьте дополнительную инициализацию перед печатью
>
void CWelcomeView::OnEndPrinting(CDO /*pDO/, CPrintlnfo* /*plnfo*/)
<
// TODO: добавьте код для «сборки мусора» после печати
>
I/ Диагностика в CWelcomeView
#ifdef _DEBUG
void CWelcomeView::AssertValid() const
<
CView::AssertValid();
>
void CWelcomeView::Dump(CDumpContext& dc) const
<
CView::Dump(dc);
>
CWelcomeDoc* CWelcomeView::GetDocument() // не-отладочная версия
// является встроенной
<
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWelcomeDoc)));
return (CWelcomeDoc*)m_pDocument;
>
#endif //_DEBUG
////////У////////////////////////////////////////////////////////////////
// Обработчики сообщений CWelcomeView
Объект вида отображает данные программы, которые обычно хранятся в объекте документа. Сейчас мы рассмотрим последний из четырех основных объектов нашей программы.

9.10.7.Исследуем объект документа
В объекте документа хранятся данные программы. В примере welcome нам потребовался только объект welcome_string. Для простоты мы разместили его в объекте вида, но на самом деле ему следовало бы находиться в объекте документа.
Как разместить welcome_string в объекте документа? Прежде всего нам следовало |
бы объявить welcome_string в заголовочном файле документа welcomeDoc.h:
// welcomeDoc.h : интерфейс класса CWelcomeDoc
////////////////////////////////////////////////////////////////////////i

INCLUDED.)
#define AFXJIELCOMEDOC_H_J\F072C89_900A_11DO_8860_444553540000__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class CWelcomeDoc : public CDocument
<
protected: // создание только при сериализации
CWelcomeDocO;

DECLAREJ)YNCREATE(CWelcomeDoc)
••> CString welcome_Strlng;


1>
Затем мы инициализируем объект welcome_string в конструкторе класса докумен-
та, расположенном в файле welcomeDoc.cpp:
CWelcomeDoc::CWelcomeDocO
<

welcome_string = «Добро пожаловать в Visual C++!»
>
Данные хранятся в объекте документа и готовы к работе — но как обратиться к ним
из объекта вида?

9.10.8. Обращение к документу из вида
Если взглянуть на код, сгенерированный АррWizard для нашего класса вида, можно заметить, что в нем уже есть фрагмент для получения указателя на объект документа с помощью метода GetDocument() класса вида. Арр Wizard присвоил этому показателю имя pDoc:
void CWelcomeView::OnDraw(CDC* pDC)
<

CWelcomeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);>
()бращение к welcome_st ring в объекте документа может выглядеть так: pDoc->welcome_I t ring; , поэтому в итоге содержимое welcome_string будет отображаться следующим образом:

void CWelcomeView::OnDraw(CDC* pDC)

CWelcomeDoc* pDoc = GetDocument();

pDC->TextOut(0, 0, pDoc->welcome_string);

>
Измененная программа будет работать как положено и выводить наше сообще-
ние. Разумеется, при таком маленьком объеме данных вряд ли стоит перемещать
их из объекта вида в объект документа. Обычно для хранения данных в послед-
нем находится одна, причем довольно веская причина — возможность записать
их на диске и затем прочесть. Давайте посмотрим, как это делается.

9.10.9. Сохранение данных на диске
Сохранение и загрузка данных будут подробно рассмотрены позднее, когда мы будем
заниматься работой с файлами, но один из аспектов этих операций можно изучить
прямо сейчас. В исходном файле документа, welcomeDoc.cpp, присутствует метод
Serialize():
void CWelcomeDoc::Serialize(CArchive& ar)

<
ar » welcome_string;
Теперь пользователь сможет сохранить документ на диске и загрузить его оттуда. ,
Позднее мы рассмотрим эту тему более подробно, а для начала хватит и этого. Исходный текст объекта документа находится в файлах welcomeDoc.h и welcomeDoc.cpp.
welcomeDoc.h и welcomeDoc.cpp
// welcomeDoc.h : интерфейс класса CWelcomeDoc
//
/////////////////////////////////////////////////////////////////////////
#if !defined(AFX_WELCOMEDOC_H__AF072C89_900AJ1DO_8860_444553540000__
INCLUDED_)
#define AFX_WELCOMEDOC_H__AF072C89_900A_1DO_8860_444553540000__INCLUDED_
# if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class CWelcomeDoc : public CDocument
<
protected: // создание только при сериализации
CwelcomeDoc();
DECLARE_DYNCREATE(CWelcomeDoc)
// Атрибуты
public:
// Операции
public:
// Переопределения
// Переопределения виртуальных функций, сгенерированные ClassWizard
// <public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//>>AFX_VIRTUAL
// Реализация
public:
virtual

CWelcomeDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Сгенерированные функции схемы сообщений
protected:
// <// ВНИМАНИЕ — здесь ClassWizard вставляет и удаляет функции класса.
/ НЕ ИЗМЕНЯЙТЕ содержимое этих частей сгенерированного кода!
//>>AFX_MSG
DECLARE_MESSAGE_MAP()
>,
///////////////////////////////////////////////////////////////////////У/
//<>
// Microsoft Visual C++ вставляет дополнительные объявления
// перед предшествующей строкой.
#endif
// idefined(AFX_WELCOMEDOC_H__AF072C89_900A_
// 11DO_8860_444553540000__INCLUDED_)
// welcomeDoc cpp : реализация класса CWelcomeDoc
//
#include «stdafx.h’
#include «welcome.h»
#include «welcomeDoc.h» ,
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////
// CWelcomeDoc
IMPLEMENT_DYNCREATE(CWelcomeDoc, CDocument)
BEGIN_MESSAGE_MAP(CWelcomeDoc, CDocument)
// <// ВНИМАНИЕ — здесь ClassWizara добавляет и удаляет макросы схемы.
// НЕ ИЗМЕНЯЙТЕ содержимое этих частей сгенерированного кода!
//>>AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////
// Создание/уничтоение CWelcomeDoc

CWelcomeDoc::CWelcomeDoc()
<
// TODO: добавьте код конструктора
>
CWelcomeDoc::

9.10.10. Декомпозиция программ
И начинающие программисты, и руководители проектов, экстраполируя ту простоту и легкость, с какой один человек может написать отдельную программу, часто полагают, что разработать программную систему также просто. Нужно только подобрать группу программистов и поручить им работу. Однако существует глубокая пропасть между написанием (небольших) про-
грамм и созданием (больших) программных систем, и многие системы по-
ставляются с опозданием, с большим количеством ошибок и обходятся в несколько раз дороже, чем по первоначальной оценке.
Разработка программного обеспечения (software engineering) имеет дело с методами организации и управления группами разработчиков, с системой обозначений и инструментальными средствами, которые поддерживают этапы процесса разработки помимо программирования. Они включают этапы технического задания, проектирования и тестирования программного обеспечения.
В этой и двух последующих главах мы изучим конструкции языков программирования, которые разработаны для того, чтобы поддерживать создание больших программных систем. Не вызывает сомнений компромисс: чем меньшую поддержку предлагает язык для разработки больших систем, тем больше потребность в методах, соглашениях и системах обозначений, которые являются внешними по отношению к самому языку. Так как язык прграммирования, несомненно, необходим, кажется разумным включить поддержку больших систем в состав самого языка и ожидать, что компилятор по возможности автоматизирует максимальную часть процесса разработки. Мы,разработчики программного обеспечения, всегда хотим автоматизировать
чью-нибудь чужую работу, но часто приходим в состояние неуверенности перед тем, как включить автоматизацию в языки программирования.
Главная проблема состоит в том, как разложить большую программную систему на легко управляемые компоненты, которые можно разработать отдельно и собрать в систему, где все компоненты взаимодействовали бы друг с другом, как запланировано. Начнем обсуждение с элементарных «механических методов» декомпозиции программы и перейдем к таким современным
понятиям, как абстрактные типы данных и объектно-ориентированное программирование, которые направляют проектировщика системы на создание семантически значимых компонентов.
Перед тем как начать обсуждение, сделаем замечание для читателей, которые только начинают изучать программирование. Понятия будут продемонстрированы на небольших примерах, которые может вместить учебник, и вам может показаться, что это всего лишь излишняя «бюрократия». Будьте уверены, что поколениями программистов был пройден тяжелый путь, доказывающий, что такая бюрократия необходима; разница только в одном, либо она определена и реализована внутри стандарта языка, либо изобретается и внедряется администрацией для каждого нового проекта.

9.10.11. Раздельная компиляция
Первоначально декомпозиция программ делалась исключительно для того,чтобы дать возможность программисту раздельно компилировать компоненты программы. Благодаря мощности современных компьютеров и эффективности компиляторов эта причина теперь не столь существенна, как раньше, но важно изучить раздельную компиляцию, потому что для ее поддержки часто используются те же самые возможности, что и для декомпозиции программы на логические компоненты. Даже в очень больших системах, которые нельзя создать без раздельной компиляции, декомпозиция на компоненты делается при проектировании программы и не имеет отношения к этапу компиляции. Поскольку программные компоненты обычно относительно невелики, лимитирующим фактором при внесении изменений в программы обычно оказывается время компоновки, а не компиляции.

Раздельная компиляция в языке Fortran
Когда был разработан Fortran, программы вводились в компьютер с помощью
перфокарт, и не было никаких дисков или библиотек программ, которые известны сегодня.
Компилируемый модуль в языке Fortran идентичен выполняемому модулю, а именно подпрограмме, называемой сабрутиной (subroutine).Каждая сабрутина компилируется не только раздельно, но и независимо, и в результате одной компиляции не сохраняется никакой информации, которую можно использовать при последующих компиляциях.
Это означает, что не делается абсолютно никакой проверки на соответствие формальных и фактических параметров. Вы можете задать значение с плававающей точкой для целочисленного параметра. Более того, массив передаётся как указатель на первый элемент, и вызванная подпрограмма никак не может узнать размер массива или даже тип элементов. Подпрограмма может даже попытаться обратиться к несуществующему фактическому параметру.
Другими словами, согласование формальных и фактических параметров задача программиста; именно он должен обеспечить правильные объявления типов и размеров параметров, как в вызывающих, так и вызываемых подпро-
граммах. Поскольку каждая подпрограмма компилируется независимо, нельзя со-
вместно использовать глобальные объявления данных. Вместо этого опреде-
лены общие (common) блоки:

subroutine S1
common /block1/ distance(100), speed(100), time(100)
real distance, speed, time
end
Это объявление требует выделить 300 ячеек памяти для значений с плаваю-
щей точкой. Все другие объявления для этого же блока распределяются в те же
самые ячейки памяти, поэтому, если другая подпрограмма объявляет:
subroutine S2
common /block/ speed(200), time(200), distance(200)
integer speed, time, distance

Не нашли то, что искали? Воспользуйтесь поиском:

Логическая система координат.

Приложения Windows могут использовать одну из нескольких логических координат , устанавливая соответствующий режим отображения в контексте отображения. При этом, как мы уже говорили, можно использовать любое направление координатных осей и любое расположение начала координат. Например, возможна система координат, в которой задаются положительные и отрицательные координаты по любой оси.

Рис. Одна из возможных систем координат

Для установки режима отображения, непосредственно определяющего направление осей и размер логической единицы системы координат, используется функция SetMapMode :

int WINAPI SetMapMode(HDC hdc, int nMapMode);

Для контекста отображения hdc эта функция устанавливает новый режим отображения, заданный параметром nMapMode, возвращая номер режима отображения, который был установлен раньше.

Параметр nMapMode может принимать одно из следующих значений.

Режим отображения Направление оси X Направление оси Y Размер одной логической единицы
MM_TEXT Вправо Вниз 1 пиксель
MM_LOMETRIC Вправо Вверх 0,1 мм
MM_HIMETRIC Вправо Вверх 0,01 мм
MM_LOENGLISH Вправо Вверх 0,01 дюйм
MM_HIENGLISH Вправо Вверх 0,001 дюйм
MM_TWIPS Вправо Вверх 1/1440 дюйма
MM_ISOTROPIC Можно выбирать Можно выбирать Произвольный, одинаковый для осей X и Y
MM_ANISOTROPIC Можно выбирать Можно выбирать Произвольный, может быть разный для осей X и Y

Как видно из этой таблицы, в режиме отображения MM_TEXT, выбранном в контекст отображения по умолчанию, используется нестандартное (для геометрии, математики и физики) направление оси Y — вниз от начала координат. Мы уже говорили, что такое направление оси Y удобно для отображения текста, поэтому этот режим отображения иногда называют текстовым.

Нетрудно заметить, что в режиме MM_TEXT логическая единица длины полностью соответствует физической, поэтому при рисовании геометрических фигур возможны искажения формы. Эти искажения связаны с тем, что форма пикселя для некоторых видеоконтроллеров может быть отличной от квадратной. Режим MM_TEXT неудобен для рисования фигур.

В режимах MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS используется более привычное направление осей координат и единицы длины, не зависящие от аппаратного обеспечения устройства вывода.

В режиме MM_ISOTROPIC вы можете выбирать произвольное направление осей координат и произвольный (но одинаковый) масштаб для осей X и Y. Заметим, что произвольное направление координат в нашем случае не подразумевает их произвольного расположения относительно вертикальной и горизонтальной осей — ось X может располагаться только горизонтально, ось Y — только вертикально.

Режим MM_ANISOTROPIC еще более универсален. Он позволяет устанавливать произвольное направление осей координат, произвольный масштаб для осей координат, причем для каждой оси можно установить свой собственный масштаб.

Во всех режимах отображения, кроме MM_TEXT и MM_ANISOTROPIC с разным масштабом для осей X и Y, приложение может не заботиться о «квадратуре пикселя», так как масштаб по осям координат одинаковый и не зависит от особенностей устройства вывода.

Сделаем небольшое пояснение относительно режима отображения MM_TWIPS. В этом режиме используется единица длины twip (от twentieth of a point — двадцатая часть точки, или, в терминах полиграфии, двадцатая часть пункта). Размер одного пункта приблизительно равен 1/72 дюйма, следовательно, размер единицы длины twip равен 1/1440 дюйма.

С помощью функции GetMapMode приложение может в любой момент времени определить номер режима отображения, выбранный в контекст отображения hdc:

int WINAPI GetMapMode(HDC hdc);

Преобразование координат.

Приложение, вызывая для рисования функции GDI, указывает логические координаты. Перед выводом GDI преобразует их в физические с использованием следующих формул:

В этих формулах используются следующие обозначения.

Переменные xWindow и yWindow обозначают, соответственно, логические координаты по оси X и Y. Физические координаты обозначаются как xViewport и yViewport. Таким образом, логические координаты (xWindow,yWindow) преобразуются в физические координаты (xViewport,yViewport).

С помощью переменных xViewOrg и yViewOrg можно изменить расположение начала физических координат. По умолчанию в контексте отображения значения атрибутов, соответствующих этим переменным, равны 0. Приложение может сместить начало координат, изменив значения переменных xViewOrg и yViewOrg.

Для перемещения начала логической системы координат приложение может изменить значения переменных xWinOrg и yWinOrg, которые также определены как атрибуты контекста отображения. По умолчанию в этих переменных находятся нулевые значения.

Переменные xViewExt, yViewExt, xWinExt и yWinExt (вернее, их отношения) задают масштаб, который используется в процессе преобразования координат. Этот масштаб зависит от установленного режима отображения. Приложения могут изменить его только в режимах MM_ISOTROPIC и MM_ANISOTROPIC, для остальных режимов отображения используются фиксированные значения.

Обратные преобразования (из логических координат в физические) выполняются с использованием следующих формул:

Для выполнения подобных вычислений удобна функция MulDiv , определенная в программном интерфейсе Windows:

int WINAPI MulDiv( int nMultiplicand, // множимое int nMultiplier, // множитель int nDivisor); // делитель

Эта функция выполняет умножение 16-разрядного параметра nMultiplicand на 16-разрядный параметр nMultiplier, а затем делит полученное 32-разрядное произведение на 16-разрядный параметр nDivisor. В случае переполнения или при нулевом значении делителя функция возвращает отрицательное значение ­32768.

Однако есть специальные функции, предназначенные для преобразования логических координат в физические и физических в логические. Это функции LPtoDP и DPtoLP.

Функция LPtoDP выполняет преобразование логических координат в физические , причем одновременно можно преобразовать несколько пар координат, что ускоряет работу приложения за счет сокращения количества вызовов функции:

BOOL WINAPI LPtoDP( HDC hdc, // идентификатор контекста отображения POINT FAR* lppt, // указатель на массив структур POINT int cPoints); // размер массива структур POINT

Параметр hdc указывает контекст отображения, для которого требуется выполнить преобразования. В процессе преобразования используются атрибуты контекста, такие как смещение и масштаб осей координат.

Через параметр lppt передается указатель на массив структур POINT, в котором находятся преобразуемые координаты. Размер массива определяется значением параметра cPoints. Структура POINT определена в файле windows.h следующим образом:

typedef struct tagPOINT < int x; int y;>POINT;

После успешного выполнения преобразования функция возвращает значение TRUE. При возникновении ошибки возвращается FALSE.

Обратное преобразование (физических координат в логические ) выполняется функцией DPtoLP :

BOOL WINAPI DPtoLP( HDC hdc, // идентификатор контекста отображения POINT FAR* lppt, // указатель на массив структур POINT int cPoints); // размер массива структур POINT

Назначение параметров функции DPtoLP и возвращаемое ей значение аналогично назначению параметров и возвращаемому значению функции LPtoDP.

Есть еще две функции, предназначенные для преобразования координат — ClientToScreen и ScreenToClient.

Функция ClientToScreen выполняет преобразование координат в системе координат, связанной с внутренней областью окна, в экранные координаты:

void WINAPI ClientToScreen(HWND hwnd, POINT FAR* lppt);

Параметр hwnd содержит идентификатор окна, для которого выполняется преобразование.

Параметр lppt содержит указатель на структуру типа POINT, в которую перед вызовом функции следует записать преобразуемые координаты.

Функция ScreenToClient имеет аналогичные параметры, но выполняет обратное преобразование:

void WINAPI ScreenToClient(HWND hwnd, POINT FAR* lppt);

Режимы отображения.

Теперь, после того как мы рассказали о физических и логических координатах, а также о преобразованиях координат, займемся подробным описанием каждого режима отображения.

Режим MM_TEXT.

Режим отображения MM_TEXT устанавливается в контексте отображения по умолчанию. Для этого режима формулы преобразования координат упрощаются:

xViewport = (xWindow — xWinOrg) + xViewOrgyViewport = (yWindow — yWinOrg) + yViewOrg

Соответствующая система координат представлена на рис. (начало системы координат расположено точно в левом верхнем углу внутренней области окна, рисунок иллюстрирует только направление координатных осей).

Рис. Система координат в режиме отображения MM_TEXT

Так как в формуле преобразования не присутствуют переменные xViewExt, yViewExt, xWinExt и yWinExt, в данном режиме преобразования невозможно изменить масштаб осей координат. Поэтому логическая единица длины в режиме отображения MM_TEXT равна физической, т. е. одному пикселю.

Илон Маск рекомендует:  Передача по ссылке

Тем не менее, приложение может изменить смещение физической или логической системы координат, изменив, соответственно, значение пар переменных (xViewOrg, yViewOrg) и (xWinOrg,yWinOrg). Для установки смещения можно использовать функции SetViewportOrg и SetWindowOrg.

Функция SetViewportOrg устанавливает смещение физической системы координат:

DWORD WINAPI SetViewportOrg( HDC hdc, // контекст отображения int nXOrigin, // новое значение для xViewOrg int nYOrigin); // новое значение для yViewOrg

Для контекста отображения hdc эта функция устанавливает новое расположение начала физической системы координат. Младшее и старшее слово возвращаемого значения содержат, соответственно, предыдущие x- и y-координаты начала физической системы координат.

С помощью функции SetWindowOrg вы можете установить начало логической системы координат:

DWORD WINAPI SetWindowOrg( HDC hdc, // контекст отображения int nXOrigin, // новое значение для xWinOrg int nYOrigin); // новое значение для yWinOrg

По своему смыслу параметры nXOrigin и nYOrigin являются логическими x- и y-координатами верхнего угла окна, используемого для отображения (так как в формуле они используются со знаком минус).

Как правило, приложения изменяют либо начало физических координат, вызывая функцию SetViewportOrg, либо начало логических координат, вызывая функцию SetWindowOrg, хотя, в принципе, вы можете изменить и то, и другое. В программном интерфейсе Windows есть варианты описанных выше двух функций, которые называются SetViewportOrgEx и SetWindowOrgEx. Они отличаются более удобным способом передачи старых координат начала соответствующей системы координат:

BOOL WINAPI SetViewportOrgEx( HDC hdc, // контекст отображения int nXOrigin, // новое значение для xWinOrg int nYOrigin, // новое значение для yWinOrg POINT FAR* lppt); // указатель на структуру POINT BOOL WINAPI SetWindowOrgEx( HDC hdc, // контекст отображения int nXOrigin, // новое значение для xWinOrg int nYOrigin, // новое значение для yWinOrg POINT FAR* lppt); // указатель на структуру POINT

В структуру, адрес которой передается через параметр lppt, записываются старые координаты начала системы координат. Обе функции возвращают TRUE в случае успеха и FALSE при возникновении ошибки.

В любой момент времени вы можете определить расположение начала физических или логических координат, если воспользуетесь функциями GetViewportOrg и GetWindowOrg (или их более новыми аналогами — GetViewportOrgEx и GetWindowOrgEx).

Функция GetViewportOrg возвращает x- и y — координаты начала физической системы координат для контекста отображения hdc:

DWORD WINAPI GetViewportOrg(HDC hdc);

Младшее и старшее слово возвращаемого значения содержат, соответственно, предыдущие x- и y-координаты начала физической системы координат.

Функция GetWindowOrg возвращает x- и y — координаты начала логической системы координат:

DWORD WINAPI GetWindowOrg(HDC hdc);

Функции GetViewportOrgEx и GetWindowExtEx записывают координаты начала координат в структуру, адрес которой передается через параметры lppt и lpSize:

BOOL WINAPI GetViewportOrgEx(HDC hdc, POINT FAR* lppt);BOOL WINAPI GetWindowExtEx(HDC hdc, SIZE FAR* lpSize);

Структура SIZE описана в файле windows.h следующим образом:

typedef struct tagSIZE < int cx; int cy;>SIZE;

Определены также разнообразные указатели на структуру SIZE:

Последнее изменение этой страницы: 2020-02-07; Нарушение авторского права страницы

Как использовать Google Tag Manager: подробное руководство для новичков

Время чтения: 16 минут Нет времени читать? Нет времени?

Диспетчер тегов упрощает интеграцию сайта со сторонними сервисами и службами аналитики. Из этой статьи вы узнаете, как установить и использовать Google Tag Manager (GTM).

Что такое Google Tag Manager

Диспетчер тегов — сервис, который упрощает использование кодов сторонних служб на сайтах или в приложениях. Благодаря Tag Manager вебмастеру достаточно один раз добавить на сайт контейнер или мастер-код. После этого код других служб можно добавлять через интерфейс диспетчера.

С помощью диспетчера тегов на сайт можно добавить код любых служб: от сервисов Google до сторонних платформ. Например, вы можете добавить код Google Analytics, «Яндекс.Метрики», Liveinternet и других служб аналитики. Это удобно, если вы пользуетесь разными сторонними сервисами для повышения эффективности и мониторинга сайта.

Можно ли обойтись без GTM? Да, если вы используете одну или две сторонних службы, диспетчером тегов можно не пользоваться. А если вы постоянно добавляете на сайт коды разных сервисов, Tag Manager упростит работу с ресурсом.

Настройка Google Tag Manager

Чтобы использовать диспетчер тегов, добавьте на сайт контейнер. Создайте пользовательские или используйте встроенные переменные. Настройте условия активации или триггеры и добавьте в контейнер теги. Подробные инструкции ниже.

Как добавить на сайт контейнер диспетчера тегов

Чтобы добавить на сайт контейнер Google Tag Manager, авторизуйтесь на странице сервиса и создайте новый аккаунт. В настройках контейнера укажите, где он будет использоваться.

Скопируйте код и вставьте его на сайт. Если вы работаете с ресурсом под управлением CMS WordPress, воспользуйтесь плагинами для вставки кода, например, Head, Footer and Post Injections. Первую часть кода вставьте в хедер как можно ближе к открывающему тегу, а вторую в тело страницы сразу после тега .

Сохраните изменения. Публиковать контейнер имеет смысл после добавления первого тега.

Как использовать переменные Google Tag Manager

Активация тегов в диспетчере происходит, когда значение триггера совпадает с заданной пользователем переменной. Например, встроенная переменная Click Text всегда содержит какой-либо текст, а переменная Click URL — URL. В данном случае триггер активируется, если значение переменной совпадает с заданными пользователем параметрами: кликом по элементу с указанным текстом или URL.

Для управления переменными выберите соответствующий раздел меню.

Здесь можно воспользоваться встроенными переменными или создать пользовательские. Чтобы использовать встроенные переменные, необходимо нажать кнопку «Настроить» и отметить нужную опцию галочкой.

Пользователям доступны следующие типы встроенных переменных:

  • Страницы. В качестве переменной вы можете выбрать полный URL (Page URL), относительный URL (Page Path), имя хоста страницы (Page Hostname), источник запроса (Page Referrer).
  • Утилиты. Этот тип переменных включает события, ID и версию контейнера, название рабочей области и ID HTML-тега.
  • Ошибки. Этот тип встроенных переменных включает просмотр контейнера в режиме отладки, а также сообщение об ошибке, URL ошибки и номер строки ошибки.
  • Клики. В качестве переменной можно использовать HTML-элементы, классы элементов, URL, текст элемента, атрибуты target и ID элемента.
  • Формы. В качестве переменной можно использовать элементы и классы формы, атрибуты target и href, а также текст формы.
  • История. Этот тип переменных поддерживает активацию триггера при изменении хеша URL. В качестве переменной можно использовать новый и старый фрагменты URL, а также новое и старое состояние истории или источник истории.

После включения переменной она становится доступной в фильтре при создании триггера.

Как использовать триггеры Google Tag Manager

Триггер — условие активации тега. Оно наступает, когда триггер совпадает с указанным значением переменной. Чтобы настроить триггер, выберите в меню соответствующий раздел и нажмите кнопку «Создать».

На странице настройки триггера укажите название и выберите тип.

В GTM доступны следующие типы триггеров:

  • Просмотр страницы. Этот тип активируется по готовности объектной модели документа (Модель DOM готова), после полной загрузки всех элементов страницы (Окно загружено) или сразу после перехода на страницу (Просмотр страницы).
  • Клик. Этот тип триггера фиксирует клики по ссылкам или любым кликабельным элементам сайта.
  • Другие типы. Здесь можно выбрать тип «Ошибка JavaScript», «Таймер», «Пользовательские события», «Отправка формы» и «Изменение в истории».

После выбора типа триггера необходимо настроить условия его активации: выбрать переменную и указать ее значение. Например, чтобы отслеживать переходы по конкретной ссылке, выберите тип переменной Click URL и укажите значение URL.

Флажок в поле «Ждать теги» блокирует действие до активации всех тегов в контейнере. Функция «Проверка ошибок» блокирует активацию тега, если пользователь выполняет ошибочное действие.

Как работают теги в GTM

Чтобы отслеживать события или использовать внешние службы, необходимо создать тег и поместить его в контейнер. Google Tag Manager поддерживает несколько десятков встроенных тегов сторонних сервисов и служб Google. Также вы можете добавлять пользовательские теги.

Принцип работы с тегами удобно осваивать на примере интеграции ресурса с системами аналитики «Яндекс.Метрика» и Google Analytics.

Подключите сайт к Google Analytics. В рабочей области воспользуйтесь функцией «Добавить новый тег». В разделе «Конфигурация тега» выберите тип тега Universal Analytics или «Классический Google Analytics». Google рекомендует пользоваться Universal Analytics.

Укажите идентификатор ресурса. Его можно найти в аккаунте Google Analytics в разделе «Администратор – Ресурс – Код отслеживания». В разделе «Тип отслеживания» выберите опцию «Просмотр страницы».

В разделе «Триггеры» выберите вариант «Все страницы». Сохраните изменения.

Подключите сайт к системе «Яндекс.Метрика». Для этого добавьте новый тег. В настройках конфигурации укажите тип «Пользовательский HTML».

В соответствующее поле вставьте код счетчика «Яндекс.Метрики». Его можно найти в разделе «Настройки» сервиса аналитики. Выберите триггер All Pages.

Перед публикацией контейнера воспользуйтесь функцией «Предварительный просмотр и отладка».

Нажмите кнопку «Предварительный просмотр». Откройте сайт в этом же браузере. Если вы установили теги верно, информация о них появится в диагностическом окне.

Опубликуйте контейнер. Проверьте корректность работы служб аналитики. В Analytics можно отправить тестовый трафик в разделе «Администратор – Ресурс – Код отслеживания». В «Метрике» корректность работы счетчика можно проверить с помощью отмеченной на иллюстрации кнопки.

Если на сайте реализованы AMP, с помощью диспетчера тегов можно подключить ускоренные страницы к службам аналитики. Если ресурс работает на WordPress, установите надстройку AMP for WordPress. В разделе Analytics включите отслеживание с помощью Tag Manager, укажите ID контейнера, тип службы аналитики и идентификатор аккаунта в Google Analytics.

Таким же способом сайт можно интегрировать с другими сервисами.

При необходимости указываете дополнительные настройки тегов. В расширенных настройках выбирайте приоритет и порядок активации тега. Игнорируйте расширенные настройки, если порядок активации тегов не имеет значения.

Ниже вы найдете рекомендации по практическому использованию Google Tag Manager.

Какие задачи можно решать с помощью диспетчера тегов Google

Благодаря контейнеру тегов GTM вам больше не нужно добавлять на сайт код, когда вы хотите расширить функциональность ресурса или подключить его к новому сервису. Вот как можно использовать это на практике.

Добавьте на сайт теги ретаргетинга и ремаркетинга

Чтобы добавить код ретаргетинга «Вконтакте» через Google Tag Manager, создайте новый тег. Выберите тип «Пользовательский HTML». Добавьте в предложенное поле код ретаргетинга. Его можно создать в разделе «Ретаргетинг» кабинета рекламодателя «Вконтакте». В поле «Триггеры активации» укажите вариант All Pages. Если код должен срабатывать при посещении некоторых страниц, укажите их URL в триггере типа «Просмотр страницы». Сохраните изменения и опубликуйте тег.

Таким же способом добавьте теги ремаркетинга и ретаргетинга других социальных сетей и рекламных систем.

Подтверждайте права на сайт с помощью Google Tag Manager

Если вы еще не подтвердили права на сайт в кабинете вебмастера Google, сделайте это с помощью диспетчера тегов. В Search Console выберите соответствующий способ и нажмите кнопку «Подтвердить».

При необходимости аналогичным способом подтвердите все версии сайта.

Добавьте кнопки шеринга на изображения

Это одна из частных возможностей мгновенной интеграции сайта со сторонними сервисами с помощью Tag Manager. Скопируйте код кнопок шеринга выбранного сервиса, например, AddThis. Создайте тег типа «Пользовательский HTML». Вставьте код кнопок. В качестве триггера активации укажите вариант All Pages. Сохраните изменения и опубликуйте контейнер.

Проверьте корректность работы кнопок шеринга.

Отслеживайте внутренние переходы на сайте

Внешние переходы удобно отслеживать с помощью UTM-меток. А внутренние клики лучше мониторить с помощью событий в Google Analytics.

Представьте, что планируете отследить переходы по конкретной ссылке. В Tag Manager выберите меню «Переменные – Настроить – Click URL». Вы активировали нужную переменную.

В разделе «Триггеры» создайте новый триггер. Выберите тип «Клик — Только ссылки».

На следующей странице отметьте галочкой опции «Ждать теги» и «Все клики по ссылкам». В качестве условия выполнения триггера укажите URL целевой страницы. Сохраните изменения.

После настройки триггера добавьте тег отслеживания. В разделе «Теги» создайте новый. В настройках конфигурации выберите тип Universal Analytics. В меню «Триггеры» выберите соответствующее значение. В настройках конфигурации заполните поля «Тип отслеживания», «Категория», «Действие», «Ярлык». Для удобства мониторинга значение в поле «Ярлык» должно соответствовать выбранному действию.

После публикации контейнера вы сможете отслеживать выбранное событие в разделе Google Analytics «Поведение – События».

Отслеживайте переходы по всем внешним ссылкам

В данном случае речь идет о кликах по любым внешним ссылкам, которые есть на сайте. Создайте пользовательскую переменную. Выберите тип компонента «Имя хоста» для переменной типа URL. Отметьте флажком опцию «Убрать www». В дополнительных настройках укажите в поле «Источник URL» значение Click URL.

Создайте триггер типа «Клик – Все элементы». В условиях активации выберите опцию «Некоторые ссылки». В фильтре укажите, что триггер активируется, если имя хоста не содержит URL вашего сайта.

Создайте тег активации триггера. Выберите тип Universal Analytics. Выберите тип отслеживания, заполните поля «Категория», «Действие» и «Ярлык». Опубликуйте тег в контейнере.

Отслеживайте переходы по конкретной внешней ссылке

Создайте пользовательскую переменную, выберите тип URL. Укажите тип компонента «Полный URL». В поле «Источник URL» выберите значение Click URL.

В условиях активации выберите значение «Некоторые ссылки». Укажите, что триггер активируется, если пользователь переходит по конкретному URL.

Сохраните триггер. Создайте тег Universal Analytics и опубликуйте его в контейнере.

Уточняйте показатель отказов

Google Analytics не точно определяет этот показатель, если пользователь во время сеанса просматривает только одну страницу. Исправить ситуацию можно с помощью Google Tag Manager.

Создайте новый триггер, укажите тип «Таймер».

В поле «Интервал» укажите время активации триггера. Например, для активации таймера через 30 секунд укажите значение 30 000 миллисекунд. В поле «Ограничение» укажите значение «1». В этом случае таймер будет активироваться один раз для каждой сессии.

В условиях активации триггера укажите URL, на которых должен срабатывать таймер.

Создайте и опубликуйте в контейнере новый тег Universal Analytics. Таймер будет активироваться каждый раз, когда посетитель будет проводить на указанных вами страницах более 30 секунд.

Если таймер будет работать на всех страницах сайта, вы сможете отслеживать в Google Analytics уточненный показатель отказов. По умолчанию система аналитики считает отказом все посещения, в ходе которых пользователь просматривает одну страницу сайта. После активации таймера сессии продолжительностью более 30 секунд не будут считаться отказами, даже если посетитель просматривает одну страницу.

Отслеживайте взаимодействие с контактной формой

Если на сайте есть контактные формы, отслеживайте заполнения с помощью GTM. Для этого в меню «Переменные» активируйте переменную Form Classes.

Создайте триггер. В настройках укажите тип «Отправка формы».

В настройках триггера переключите галочку в положение «Некоторые формы». Укажите в качестве условий активации «Фильтр Form Classes содержит» и укажите значение атрибута class формы.

Создайте соответствующий тег Universal Analytics. Сохраните изменения и опубликуйте контейнер. Значение атрибута class формы можно найти в коде страницы.

Отслеживайте клики по социальным кнопкам и виджетам

Практически на каждом сайте есть социальные плагины, например, виджеты страниц в Facebook и «Вконтакте», кнопки Follow Me. С помощью диспетчера тегов можно отслеживать клики по конверсионным кнопкам виджетов типа «Нравится» или «Подписаться». Например, настройте отслеживание кликов по иконке Twitter в блоке Follow Me.

В меню «Переменные» активируйте переменную Click Classes.

Создайте триггер, выберите тип «Клик — все элементы». Переключите флажок в положение «Некоторые клики». В фильтре активации укажите значение атрибута class кнопки Twitter из блока Follow Me. Его можно найти в коде элемента.

Добавьте данные в фильтр диспетчера тегов, сохраните изменения. Создайте соответствующий тег Universal Analytics и опубликуйте обновленный контейнер.

Отслеживайте переходы по тексту клика

Эту функцию можно использовать для проверки эффективности CTR элементов ресурса. Представьте, что на сайте есть одинаковые кнопки с разным призывом к действию. Чтобы определить, какие кнопки нажимают чаще, активируйте переменную Click Text.

Создайте триггер, выберите тип «Клик – Все элементы». Установите галочку в положение «Некоторые клики». Выберите фильтр Click Text. В качестве условия активации триггера отметьте «Содержит» и укажите нужный текст.

Создайте и опубликуйте тег Google Analytics.

Отслеживайте конкретные источники внешнего трафика

С помощью Google Tag Manager удобно мониторить количество посетителей с конкретных сайтов. Для этого создайте триггер. Выберите тип «Просмотр страницы». В качестве переменной укажите Referrer. В качестве правила активации укажите «Содержит» и добавьте URL источника, который планируете отслеживать.

Создайте тег с типом отслеживания «Событие» и опубликуйте его в контейнере. После этого Google Analytics будет фиксировать событие при каждом посещении сайта из выбранного источника.

Чтобы отслеживать посещения с конкретной страницы, в качестве переменной укажите Referrer, а в правилах активации отметьте «Равно» и добавьте полный URL страницы.

Используйте GTM для внедрения микроразметки

Используйте эту рекомендацию, если внедряете на сайте универсальные типы микроразметки. Они содержат одинаковые данные независимо от страницы сайта. Например, внедрите тип разметки Organization.

Воспользуйтесь генератором Schema JSON-LD или аналогичным инструментом, чтобы получить код. Создайте тег типа «Пользовательский HTML». Вставьте код разметки. Выберите триггер активации All Pages.

Отслеживайте источники трафика с помощью событий Google Analytics

Эту функцию можно использовать, чтобы быстро оценить количество источники трафика и количество посещений с того или иного сайта.

Создайте пользовательскую переменную типа «Источник ссылки HTTP». Укажите тип компонента «Имя хоста».

Создайте триггер типа «Просмотр страниц». В условиях активации укажите, что тег активируется, если URL источника не совпадает с URL вашего сайта.

Создайте и опубликуйте в контейнере тег Google Analytics. После этого в разделе «События – Обзор – Категория событий» Google Analytics можно оценивать источники трафика.

Это далеко не все возможности диспетчера тегов. Предложенные примеры помогут освоить принцип работы GTM. После этого вы сможете самостоятельно выбирать параметры для мониторинга с помощью служб аналитики и добавлять на сайт коды интернет-сервисов.

Находка для нетехнических специалистов

Именно так можно коротко охарактеризовать Google Tag Manager. Этот инструмент избавляет владельца сайта от трудностей при интеграции со сторонними сервисами. Достаточно один раз установить контейнер, чтобы забыть о необходимости вставлять код на сайт вручную.

Диспетчер тегов упрощает мониторинг и аналитику эффективности сайта. С помощью набора встроенных и пользовательских переменных вы можете быстро настроить отслеживание практически любых событий на сайте.

Работа с контекстом отображения

В этой главе вы научитесь получать контекст отображения и контекст устройства , изменять его атрибуты и рисовать простейшие графические изображения на экране монитора. Вопросы, связанные с использованием цвета, цветовых палитр, вывода текста и графических изображений bitmap, а также печати на принтере будут рассмотрены в следующих главах нашей книги.

Как правило, приложения выполняют всю работу по рисованию во время обработки сообщения WM_PAINT , хотя часто требуется рисовать и во время обработки других сообщений. В любом случае приложение должно придерживаться следующей последовательности действий:

  • получение или создание контекста отображения;
  • установка необходимых атрибутов в контексте отображения;
  • выполнение операций рисования;
  • освобождение или удаление контекста отображения.

Последнее действие (освобождение или удаление контекста отображения) должно быть обязательно выполнено. Самый простой способ полностью нарушить работоспособность Windows — забыть освободить полученный контекст отображения или удалить созданный контекст отображения или устройства.

Так как контекст отображения — критический ресурс, его необходимо освобождать сразу, как только в нем отпадет необходимость. Операционная система Windows выполняет кеширование обычного контекста отображения (есть и необычные контексты отображения, но об этом позже), причем кешируются только пять контекстов. Если Windows не может удовлетворить запрос какого-либо приложения на выделение контекста отображения, вся операционная система окажется в критическом состоянии, единственным выходом из которого будет полный перезапуск Windows.

Среди всех атрибутов контекста отображения, описанных в первой главе, особое место занимает режим отображения, влияющий на систему координат и, соответственно, на работу практически всех функций рисования. Поэтому необходимо уделить особое внимание вопросам использования режимов отображения и систем координат.

Однако прежде всего необходимо научиться получать и освобождать контекст отображения.

Способы получения (и, соответственно, освобождения) контекста отображения разные для контекстов разного типа. Можно выделить следующие типы контекста отображения:

  • общий контекст отображения (common display context);
  • контекст отображения для класса окна (class display context);
  • личный контекст отображения (private display context);
  • родительский контекст отображения (parent display context);
  • контекст отображения для окна (window display context);
  • контекст физического устройства (device context);
  • информационный контекст (information context);
  • контекст для памяти (memory device context);
  • контекст для метафайла (metafile context).

Каждый из перечисленных выше контекстов имеет свои особенности и свое назначение.

Общий контекст отображения

Этот контекст используется чаще всего и поэтому для ускорения доступа к нему Windows использует кеширование (как мы уже говорили, размер кеша достаточен для хранения только пяти контекстов отображения).

Для получения общего контекста отображения приложение должно вызвать функцию BeginPaint (при обработке сообщения WM_PAINT ) или GetDC (при обработке других сообщений). При этом перед регистрацией класса окна в поле стиля класса окна в структуре WNDCLASS не должны использоваться значения CS_OWNDC , CS_PARENTDC или CS_CLASSDC :

Функция BeginPaint возвращает контекст отображения для окна hwnd:

Перед этим она подготавливает указанное окно для рисования, заполняя структуру типа PAINTSTRUCT (адрес которой передается через параметр lpps) информацией, которую можно использовать в процессе рисования.

Структура PAINTSTRUCT и указатели на нее (различных типов) описаны в файле windows.h:

Рассмотрим назначение отдельных полей структуры PAINTSTRUCT.

Поле hdc после возврата из функции будет содержать идентификатор полученного контекста отображения, который должен передаваться в качестве параметра функциям интерфейса GDI, выполняющим рисование. Можно использовать также значение идентификатора контекста, возвращенное функцией BeginPaint, так как эти значения одинаковые.

Анализируя содержимое поля fErase, приложение может определить, нужно ли перерисовывать фон окна. Если в этом поле находится значение TRUE, фон окна должен быть перерисован. Такая необходимость может возникнуть в том случае, если в классе, на базе которого создано окно, при регистрации не была выбрана кисть для закрашивания фона (поле hbrBackground структуры WNDCLASS).

Поле rcPaint, которое представляет собой структуру типа RECT, содержит координаты верхнего левого и правого нижнего угла прямоугольника, внутри которого нужно рисовать. Напомним вам формат структуры RECT , описанной в файле windows.h:

Мы уже говорили вам в 11 томе «Библиотеки системного программиста», что при обработке сообщения WM_PAINT приложение должно суметь перерисовать все окно или любую его часть. Сообщение WM_PAINT может попасть в функцию окна в том случае, если все окно или его часть требуют перерисовки. Поле rcPaint в структуре PAINTSTRUCT содержит координаты прямоугольной области, расположенной в окне и требующей перерисовки.

Остальные поля зарезервированы для Windows и не используются приложениями.

Контекст отображения, полученный при помощи функции BeginPaint, необходимо освободить перед завершением обработки сообщения WM_PAINT, вызвав функцию EndPaint :

Функции EndPaint передаются те же параметры, что и функции BeginPaint.

Обычно обработчик сообщения WM_PAINT выглядит следующим образом:

Подобный фрагмент кода вы можете найти в приложениях, описанных в одном из предыдущих томов «Библиотеки системного программиста».

Функции BeginPaint и EndPaint можно использовать только внутри обработчика сообщения WM_PAINT. Если же приложению требуется рисовать во время обработки других сообщений, оно должно получить контекст отображения с помощью функции GetDC . После завершения процедуры рисования перед выходом из обработчика сообщения следует освободить полученный контекст отображения, вызвав функцию ReleaseDC .

Функция GetDC возвращает контекст отображения для окна с идентификатором hwnd:

Полученный таким образом контекст отображения можно использовать для рисования во внутренней области окна (window client region).

Функция ReleaseDC освобождает контекст отображения hdc, полученный для окна hwnd:

Мы еще раз обращаем ваше внимание на необходимость своевременного освобождения общего контекста отображения.

Каждый раз, когда приложение получает общий контекст отображения, его атрибуты принимают значения по умолчанию, перечисленные нами ранее. Если перед выполнением рисования приложение изменит атрибуты контекста отображения, вызвав соответствующие функции GDI, в следующий раз при получении общего контекста отображения эти атрибуты снова примут значения по умолчанию. Поэтому установка атрибутов должна выполняться каждый раз после получения общего контекста отображения. Такая процедура отнимает дополнительное время, но она необходима при использовании контекста отображения этого типа.

Контекст отображения для класса окна

Общий контекст отображения , описанный нами в предыдущем разделе, кешируется операционной системой Windows для ускорения доступа к нему. Однако вы можете создать такой контекст отображения, который хранится отдельно в единственном экземпляре и используется всеми окнами, созданными на базе класса окна. При регистрации такого класса окна вы должны указать стиль CS_CLASSDC :

Все окна, созданные на базе класса, имеющего стиль CS_CLASSDC, будут использовать один общий контекст отображения.

В отличие от общего контекста отображения, приложения, однажды получив контекст отображения для класса окна, могут не освобождать его. То есть для контекста этого типа после функций BeginPaint и GetDC можно не вызывать функции EndPaint и ReleaseDC. Если же приложение вызовет функцию EndPaint или ReleaseDC, они не будут ничего делать и сразу вернут управление. Для уменьшения вероятности ошибки мы рекомендуем вам всегда освобождать контекст отображения, даже если это и не требуется для данного типа контекста.

Несмотря на то, что для всех окон, созданных на базе класса стиля CS_CLASSDC, создается один контекст отображения, не следует думать, что приложение, однажды получив этот контекст, не должно получать его вновь при очередном вызове обработчика сообщения, выполняющего рисование.

Дело в том, что при получении контекста отображения для окна в нем устанавливаются атрибуты области ограничения и начало системы физических координат устройства отображения. Если на базе нашего класса создано несколько окон, при получении ими контекста отображения эти атрибуты «настраиваются» на окно, получившее контекст отображения. Но если на базе класса стиля CS_CLASSDC приложение создало только одно окно, оно может получить контекст отображения для класса окна один раз и не освобождать его.

Зачем используется контекст отображения класса окна?

Вы можете использовать его в тех случаях, когда по соображениям повышения производительности нежелательно выполнять настройку многочисленных атрибутов контекста отображения после каждого вызова функции BeginPaint или EndPaint. Эту настройку можно выполнить только один раз. Каждый раз, когда функция окна получает контекст отображения класса окна, в нем выполняется настройка только двух атрибутов — области ограничения и начала системы физических координат устройства вывода. Остальные атрибуты остаются без изменений и, следовательно, не требуют повторной настройки.

Личный контекст отображения

Указав в стиле класса окна значение CS_OWNDC , можно добиться того, что для каждого окна, созданного на базе такого класса, Windows создаст отдельную структуру контекста отображения:

Личный контекст отображения можно, получив один раз, никогда не освобождать. Вы можете один раз настроить атрибуты контекста отображения сразу после получения самого контекста и использовать полученный контекст без изменений до завершения работы приложения.

Однако не будет ошибкой, если приложение будет использовать личный контекст отображения как общий, то есть каждый раз при обработке сообщения WM_PAINT (или другого сообщения, обработчик которого занимается рисованием) оно будет получать контекст и затем отдавать его. Соответствующие функции (BeginPaint, EndPaint, GetDC, ReleaseDC) будут возвращать управление, не выполняя никаких действий.

Личный контекст проще в использовании, так как его можно получать и настраивать только один раз, однако оперативная память будет расходоваться менее экономно.

Родительский контекст отображения

Родительский контекст отображения используется для дочерних окон. Он позволяет дочерним окнам «унаследовать» атрибуты контекста отображения у родительского окна, что во многих случаях упрощает процедуру настройки этих атрибутов. Например, дочернее окно может использовать для вывода текста тот же шрифт и цвета, что и родительское окно.

Для использования родительского контекста отображения в классе, на базе которого создается дочернее окно, перед регистрацией необходимо указать стиль CS_PARENTDC :

Контекст отображения для окна

Все описанные выше контексты отображения позволяют рисовать только во внутренней области окна (client region). С помощью функции GetWindowDC приложение может получить контекст отображения для окна , позволяющий рисовать в любом месте окна (в области заголовка окна, в области системного меню, рамки окна, кнопок изменения размера и т. п.).

Контекст отображения, полученный для окна, используется аналогично общему контексту отображения. После получения контекста его атрибуты принимают значения по умолчанию. Приложение обязано освобождать этот контекст сразу после использования, вызывая функцию ReleaseDC.

Особенностью данного контекста является то, что в нем выбрана система координат, начало которой находится в левом верхнем углу окна (всего окна, а не его внутренней области).

Такой контекст может использоваться при необходимости заменить стандартные элементы окна (заголовок, полосы просмотра и т. п.) на собственные, или если приложение желает нарисовать что-нибудь в области заголовка или рамки.

Контекст физического устройства

Вывод изображений на такое устройство, как принтер, может выполняться с использованием тех же приемов, что и вывод в окно приложения. Прежде всего необходимо получить контекст устройства . Затем можно вызывать функции GDI, выполняющие рисование, передавая им идентификатор полученного контекста в качестве параметра.

В отличие от контекста отображения, контекст физического устройства не получается, а создается, для чего используется функция CreateDC :

Параметр lpszDriver является указателем на строку символов, содержащую имя драйвера, обслуживающего физическое устройство. Имя драйвера совпадает с именем файла *.drv, содержащего сам драйвер и расположенного в системном каталоге Windows.

Имя устройства lpszDevice — это название самого устройства, описанное, например, в файле win.ini в разделе [devices].

Параметр lpszOutput указывает на структуру данных типа DEVMODE, используемую при инициализации устройства вывода. Если при работе с устройством нужно использовать параметры, установленные при помощи приложения Control Panel, параметр lpszOutput следует указать как NULL.

Более подробно вопросы работы с принтером будут рассмотрены в отдельной главе этого тома.

В приведенном ниже примере создается контекст устройства для лазерного принтера HP Laserjet III, подключенного к порту LPT1:, причем в системном каталоге Windows для этого принтера установлен драйвер hppcl5a.drv:

Аналогично, для принтера Epson FX-850, подключенного к порту LPT2:, и работающему через драйвер epson9.drv:

Созданный при помощи функции CreateDC контекст устройства следует удалить (но не освободить), вызвав функцию DeleteDC:

Эта функция возвращает TRUE при нормальном завершении и FALSE при возникновении ошибки.

Контекст для устройства DISPLAY

В некоторых случаях требуется получить контекст отображения, позволяющий приложению рисовать в любом месте экрана дисплея. Такой контекст можно создать при помощи функции CreateDC, указав в качестве имени драйвера строку «DISPLAY «, а в качестве остальных параметров — значение NULL:

В данном случае будет создан контекст для видеомонитора, с помощью которого приложение может рисовать в любом месте экрана. Начало системы координат, выбранной в данный контекст, располагается в верхнем левом углу экрана видеомонитора.

После использования созданный таким образом контекст отображения следует удалить, вызвав функцию DeleteDC.

Есть еще два способа получения контекста для экрана.

Приложение может получить контекст отображения для всего экрана при помощи функции GetDC, указав в качестве параметра значение NULL:

Полученный таким образом контекст следует освободить после использования при помощи функции ReleaseDC, передав ей вместо идентификатора окна значение NULL:

Еще один способ связан с использованием функции GetDCEx, описание которой будет приведено ниже.

Информационный контекст

Если приложению необходимо получить информацию об устройстве вывода (например, с помощью функции GetDeviceCaps, рассмотренной нами в 11 томе «Библиотеки системного программиста»), оно может создать вместо обычного информационный контекст . Информационный контекст нельзя использовать для рисования, однако он занимает меньше места в памяти.

Информационный контекст создается при помощи функции CreateIC , аналогичной по своим параметрам функции CreateDC:

После использования информационный контекст следует удалить, вызвав функцию DeleteDC.

Контекст для памяти

В работе с битовыми изображениями bitmap часто используется такое «устройство вывода», как оперативная память. Приложение может полностью подготовить изображение в оперативной памяти, получив контекст для памяти , и затем быстро вывести готовое изображение на экран. Этот способ во многих случаях работает намного быстрее и приятнее для пользователя, чем формирование изображения непосредственно на экране.

Контекст для памяти создается совместимым с тем контекстом отображения, в котором будет выполняться вывод на физическое устройство. Для создания совместимого контекста используется функция CreateCompatibleDC :

Созданный таким образом контекст памяти удаляется при помощи функции DeleteDC.

Использование контекста памяти будет подробно описано в главе, посвященной битовым изображениям bitmap.

Контекст для метафайла

Контекст для метафайла позволяет записывать команды GDI в файл и затем проигрывать такой файл на физическом устройстве вывода. Файл может находиться в памяти или на диске, в последнем случае его можно использовать для переноса графического изображения в другое приложение.

Для создания контекста метефайла используется функция CreateMetaFile :

Параметр lpszFileName должен указывать на строку, содержащую путь к имени файла, в который будут записаны команды GDI, или NULL. В последнем случае создается метафайл в оперативной памяти.

После выполнения рисования в контексте метафайла следует закрыть метафайл, вызвав функцию CloseMetaFile :

Эта функция закрывает метафайл для контекста hdc и возвращает идентификатор метафайла. Идентификатор закрытого метафайла использовать нельзя, так как он не содержит никакой полезной информации.

Что можно сделать с полученным идентификатором метафайла?

Можно скопировать метафайл в обычный дисковый файл, вызвав функцию CopyMetaFile :

Параметр hmf определяет метафайл, параметр lpszFileName содержит путь к имени файла, в который будет записан метафайл .

Можно проиграть метафайл в контексте отображения или контексте устройства, вызвав функцию PlayMetaFile :

Наконец, при помощи функции DeleteMetaFile можно удалить метафайл:

Удаление метафайла с помощью функции DeleteMetaFile делает недействительным идентификатор метафайла hmf и освобождает оперативную память, занятую метафайлом. Если метафайл был создан как обычный дисковый файл, функция DeleteMetaFile не удаляет его с диска.

Для того чтобы воспользоваться метафайлом, хранящимся в виде дискового файла, его следует загрузить при помощи функции GetMetaFile , указав ей в качестве единственного параметра путь к соответствующему файлу:

Функция GetDCEx

В программном интерфейсе операционной системы Windows версии 3.1 появилась функция GetDCEx , предоставляющая расширенные возможности для получения контекста отображения:

Функция возвращает идентификатор полученного контекста отображения или NULL при ошибке.

Параметр hwnd задает идентификатор окна, для которого необходимо получить контекст отображения.

С помощью параметра hrgnClip можно определить область ограничения вывода. Эта область может иметь произвольную форму и являться комбинацией нескольких областей ограничения. Использование областей ограничения будет подробно описано дальше в этой главе.

Параметр flags определяет способ, которым будет образован контекст отображения. Этот параметр можно указывать как логическую комбинацию следующих значений:

Константа Описание
DCX_WINDOW Функция возвращает контекст отображения, позволяющий рисовать во всем окне, а не только в его внутренней области
DCX_CACHE Функция получает общий контекст отображения из кеша Windows, даже если окно создано на базе класса стиля CS_OWNDC или CS_CLASSDC
DCX_CLIPCHILDREN Видимые области всех дочерних окон, расположенных ниже окна hwnd, исключаются из области отображения
DCX_CLIPSIBLINGS Видимые области всех окон-братьев (окон, имеющих общих родителей), расположенных выше окна hwnd, исключаются из области отображения
DCX_PARENTCLIP Для отображения используется вся видимая область родительского окна, даже если родительское окно создано с использованием стилей WS_CLIPCHILDREN и WS_PARENTDC. Начало координат устанавливается в левый верхний угол окна hwnd
DCX_EXCLUDERGN Если указан этот флаг, при выводе будет использована область ограничения, заданная параметром hrgnClip
DCX_INTERSECTRGN Используется пересечение области ограничения, заданной параметром hrgnClip, и видимой области полученного контекста отображения
DCX_LOCKWINDOWUPDATE Этот флаг разрешает рисование в окне, заблокированном для рисования функцией LockWindowUpdate . Флаг можно использовать при необходимости рисовать, например, рамку, выделяющую произвольную область экрана

Контекст отображения, полученный функцией GetDCEx, следует освободить после использования при помощи функции ReleaseDC.

Напомним, что режим отображения — это атрибут контекста отображения, влияющий на используемую функциями GDI систему координат. Для обеспечения независимости приложений от аппаратного обеспечения приложения Windows работают с логическими координатами, которые отображаются в физические. Приложения Windows (в отличие от программ MS-DOS) могут не знать номер используемого видеорежима и соответствующее ему разрешение по вертикали и горизонтали в пикселах, определяя размеры элементов формируемого изображения в миллиметрах или дюймах. Хотя в качестве единицы измерения можно использовать и пиксел, если выбрать соответствующий режим отображения.

Из уроков геометрии в школе и институте вы знаете, что существуют различные системы координат, каждая из которых удобна в том или ином случае. Мы не будем описывать все возможные системы координат, ограничившись доступными в Windows версии 3.1 (в операционной системе Windows NT набор систем координат немного расширен).

Изучение режимов отображения Windows версии 3.1 мы начнем с определения основных понятий и терминов, имеющих отношение к системам координат и преобразованию логических координат в физические.

Основные определения

Прежде всего необходимо определить понятия «физические координаты » и «логические координаты «.

Физические координаты, как это следует из названия, имеют непосредственное отношение к физическому устройству вывода. В качестве единицы измерения длины в системе физических координат всегда используется пиксел. Если устройством вывода является экран монитора, физические координаты обычно называют экранными координатами.

Логические координаты передаются функциям GDI, выполняющим рисование фигур или вывод текста. Используемые единицы измерения зависят от режима отображения.

При отображении GDI преобразует логические координаты в физические. Способ преобразования зависит от режима отображения и других атрибутов контекста отображения, таких как расположение начала системы координат для окна, расположение начала системы физических координат, масштаб осей для окна и масштаб осей физических координат.

Физическая система координат

На рис. 2.1 показана физическая система координат для экрана видеомонитора.

Рис. 2.1. Физическая система координат для экрана видеомонитора

Начало этой системы координат располагается в левом верхнем углу экрана. Ось X направлена слева направо, ось Y — сверху вниз. В качестве единицы длины в данной системе координат используется пиксел.

Для того чтобы определить физическое разрешение устройства вывода (например, размер экрана в пикселах по вертикали и горизонтали), следует использовать функцию GetDeviceCaps , которую мы рассмотрели в 11 томе «Библиотеки системного программиста». Если передать в качестве второго параметра этой функции значения VERTRES и HORZRES , она в любом режиме отображения вернет, соответственно, размер экрана в пикселах по вертикали и по горизонтали. Параметр hdc должен указывать информационный контекст или контекст отображения, связанный с экраном монитора:

Физическая система координат «привязана» к физическому устройству вывода, поэтому при ее использовании для вывода изображения следует учитывать особенности видеоконтроллера. В 11 томе «Библиотеки системного программиста» в разделе, посвященном метрикам операционной системы Windows, мы подробно рассказали об использовании функции GetDeviceCaps для исследования пространственных характеристик монитора. Для удобства мы воспроизведем приведенную в этом томе таблицу некоторых метрик для видеомониторов различных типов.

Параметр функции GetDeviceCaps CGA EGA VGA SVGA 800 x 600 8514/A SVGA 1024 x 768
HORZRES 640 640 640 800 1024 1024
VERTRES 200 350 480 600 760 768
HORZSIZE 240 240 208 208 280 208
VERTSIZE 180 175 156 152 210 152
ASPECTX 5 38 36 36 10 36
ASPECTY 12 48 36 36 14 36
ASPECTXY 13 61 51 51 14 51
LOGPIXELSX 96 96 96 96 120 96
LOGPIXELSY 48 72 96 96 120 96

Из этой таблицы видны недостатки физической системы координат.

Во-первых, вертикальное (VERTRES) и горизонтальное (HORZRES) разрешение зависит от типа видеоконтроллера.

Во-вторых, физические размеры пикселов (ASPECTX и ASPECTY ), и, что самое главное, отношение высоты и ширины пиксела также зависят от типа видеоконтроллера.

Если приложению требуется нарисовать, например, окружность или квадрат, при использовании физической системы координат придется учитывать форму пикселов, выполняя масштабирование изображения по одной из осей координат. В противном случае вместо окружности и квадрата на экране появятся эллипс и прямоугольник.

Логическая система координат

Приложения Windows могут использовать одну из нескольких логических координат , устанавливая соответствующий режим отображения в контексте отображения. При этом, как мы уже говорили, можно использовать любое направление координатных осей и любое расположение начала координат. Например, возможна система координат, в которой задаются положительные и отрицательные координаты по любой оси (рис. 2.2).

Рис. 2.2. Одна из возможных систем координат

Для установки режима отображения, непосредственно определяющего направление осей и размер логической единицы системы координат, используется функция SetMapMode :

Для контекста отображения hdc эта функция устанавливает новый режим отображения, заданный параметром nMapMode, возвращая номер режима отображения, который был установлен раньше.

Параметр nMapMode может принимать одно из следующих значений.

Режим отображения Направление оси X Направление оси Y Размер одной логической единицы
MM_TEXT Вправо Вниз 1 пиксел
MM_LOMETRIC Вправо Вверх 0,1 мм
MM_HIMETRIC Вправо Вверх 0,01 мм
MM_LOENGLISH Вправо Вверх 0,01 дюйм
MM_HIENGLISH Вправо Вверх 0,001 дюйм
MM_TWIPS Вправо Вверх 1/1440 дюйма
MM_ISOTROPIC Можно выбирать Можно выбирать Произвольный, одинаковый для осей X и Y
MM_ANISOTROPIC Можно выбирать Можно выбирать Произвольный, может быть разный для осей X и Y

Как видно из этой таблицы, в режиме отображения MM_TEXT, выбранном в контекст отображения по умолчанию, используется нестандартное (для геометрии, математики и физики) направление оси Y — вниз от начала координат. Мы уже говорили, что такое направление оси Y удобно для отображения текста, поэтому этот режим отображения иногда называют текстовым.

Нетрудно заметить, что в режиме MM_TEXT логическая единица длины полностью соответствует физической, поэтому при рисовании геометрических фигур возможны искажения формы. Эти искажения связаны с тем, что форма пиксела для некоторых видеоконтроллеров может быть отличной от квадратной. Режим MM_TEXT неудобен для рисования фигур.

В режимах MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS используется более привычное направление осей координат и единицы длины, не зависящие от аппаратного обеспечения устройства вывода.

В режиме MM_ISOTROPIC вы можете выбирать произвольное направление осей координат и произвольный (но одинаковый) масштаб для осей X и Y. Заметим, что произвольное направление координат в нашем случае не подразумевает их произвольного расположения относительно вертикальной и горизонтальной осей — ось X может располагаться только горизонтально, ось Y — только вертикально.

Режим MM_ANISOTROPIC еще более универсален. Он позволяет устанавливать произвольное направление осей координат, произвольный масштаб для осей координат, причем для каждой оси можно установить свой собственный масштаб.

Во всех режимах отображения, кроме MM_TEXT и MM_ANISOTROPIC с разным масштабом для осей X и Y, приложение может не заботиться о «квадратуре пиксела», так как масштаб по осям координат одинаковый и не зависит от особенностей устройства вывода.

Сделаем небольшое пояснение относительно режима отображения MM_TWIPS. В этом режиме используется единица длины twip (от twentieth of a point — двадцатая часть точки, или, в терминах полиграфии, двадцатая часть пункта). Размер одного пункта приблизительно равен 1/72 дюйма, следовательно размер единицы длины twip равен 1/1440 дюйма.

С помощью функции GetMapMode приложение может в любой момент времени определить номер режима отображения, выбранный в контекст отображения hdc:

Преобразование координат

Теперь немного математики (не волнуйтесь, совсем немного).

Приложение, вызывая для рисования функции GDI, указывает логические координаты. Перед выводом GDI преобразует их в физические с использованием следующих формул:

В этих формулах используются следующие обозначения.

Переменные xWindow и yWindow обозначают, соответственно, логические координаты по оси X и Y. Физические координаты обозначаются как xViewport и yViewport. Таким образом, логические координаты (xWindow,yWindow) преобразуются в физические координаты (xViewport,yViewport).

С помощью переменных xViewOrg и yViewOrg можно изменить расположение начала физических координат. По умолчанию в контексте отображения значения атрибутов, соответствующих этим переменным, равны 0. Приложение может сместить начало координат, изменив значения переменных xViewOrg и yViewOrg.

Для перемещения начала логической системы координат приложение может изменить значения переменных xWinOrg и yWinOrg, которые также определены как атрибуты контекста отображения. По умолчанию в этих переменных находятся нулевые значения.

Переменные xViewExt, yViewExt, xWinExt и yWinExt (вернее, их отношения) задают масштаб, который используется в процессе преобразования координат. Этот масштаб зависит от установленного режима отображения. Приложения могут изменить его только в режимах MM_ISOTROPIC и MM_ANISOTROPIC , для остальных режимов отображения используются фиксированные значения.

Обратные преобразования (из логических координат в физические) выполняются с использованием следующих формул:

Для выполнения подобных вычислений удобна функция MulDiv , определенная в программном интерфейсе Windows:

Эта функция выполняет умножение 16-разрядного параметра nMultiplicand на 16-разрядный параметр nMultiplier, а затем делит полученное 32-разрядное произведение на 16-разрядный параметр nDivisor. В случае переполнения или при нулевом значении делителя функция возвращает отрицательное значение ­32768.

Однако есть специальные функции, предназначенные для преобразования логических координат в физические и физических в логические. Это функции LPtoDP и DPtoLP.

Функция LPtoDP выполняет преобразование логических координат в физические , причем одновременно можно преобразовать несколько пар координат, что ускоряет работу приложения за счет сокращения количества вызовов функции:

Параметр hdc указывает контекст отображения, для которого требуется выполнить преобразования. В процессе преобразования используются атрибуты контекста, такие как смещение и масштаб осей координат.

Через параметр lppt передается указатель на массив структур POINT, в котором находятся преобразуемые координаты. Размер массива определяется значением параметра cPoints. Структура POINT определена в файле windows.h следующим образом:

После успешного выполнения преобразования функция возвращает значение TRUE. При возникновении ошибки возвращается FALSE.

Обратное преобразование (физических координат в логические ) выполняется функцией DPtoLP :

Назначение параметров функции DPtoLP и возвращаемое ей значение аналогично назначению параметров и возвращаемому значению функции LPtoDP.

Есть еще две функции, предназначенные для преобразования координат — ClientToScreen и ScreenToClient.

Функция ClientToScreen выполняет преобразование координат в системе координат, связанной с внутренней областью окна, в экранные координаты:

Параметр hwnd содержит идентификатор окна, для которого выполняется преобразование.

Параметр lppt содержит указатель на структуру типа POINT, в которую перед вызовом функции следует записать преобразуемые координаты.

Функция ScreenToClient имеет аналогичные параметры, но выполняет обратное преобразование:

Режимы отображения

Теперь, после того как мы рассказали о физических и логических координатах, а также о преобразованиях координат, займемся подробным описанием каждого режима отображения .

Режим MM_TEXT

Режим отображения MM_TEXT устанавливается в контексте отображения по умолчанию. Для этого режима формулы преобразования координат упрощаются:

Соответствующая система координат представлена на рис. 2.3 (начало системы координат расположено точно в левом верхнем углу внутренней области окна, рисунок иллюстрирует только направление координатных осей).

Рис. 2.3. Система координат в режиме отображения MM_TEXT

Так как в формуле преобразования не присутствуют переменные xViewExt, yViewExt, xWinExt и yWinExt, в данном режиме преобразования невозможно изменить масштаб осей координат. Поэтому логическая единица длины в режиме отображения MM_TEXT равна физической, т. е. одному пикселу.

Тем не менее, приложение может изменить смещение физической или логической системы координат, изменив, соответственно, значение пар переменных (xViewOrg, yViewOrg) и (xWinOrg,yWinOrg). Для установки смещения можно использовать функции SetViewportOrg и SetWindowOrg.

Функция SetViewportOrg устанавливает смещение физической системы координат:

Для контекста отображения hdc эта функция устанавливает новое расположение начала физической системы координат. Младшее и старшее слово возвращаемого значения содержат, соответственно, предыдущие x- и y-координаты начала физической системы координат.

С помощью функции SetWindowOrg вы можете установить начало логической системы координат:

По своему смыслу параметры nXOrigin и nYOrigin являются логическими x- и y-координатами верхнего угла окна, используемого для отображения (так как в формуле они используются со знаком минус).

Как правило, приложения изменяют либо начало физических координат, вызывая функцию SetViewportOrg, либо начало логических координат, вызывая функцию SetWindowOrg, хотя, в принципе, вы можете изменить и то, и другое (если не боитесь запутаться в координатных «сетях»).

В программном интерфейсе Windows версии 3.1 есть новые варианты описанных выше двух функций, которые называются SetViewportOrgEx и SetWindowOrgEx . Они отличаются более удобным способом передачи старых координат начала соответствующей системы координат:

В структуру, адрес которой передается через параметр lppt, записываются старые координаты начала системы координат. Обе функции возвращают TRUE в случае успеха и FALSE при возникновении ошибки.

В любой момент времени вы можете определить расположение начала физических или логических координат, если воспользуетесь функциями GetViewportOrg и GetWindowOrg (или их более новыми аналогами — GetViewportOrgEx и GetWindowOrgEx).

Функция GetViewportOrg возвращает x- и y-координаты начала физической системы координат для контекста отображения hdc:

Младшее и старшее слово возвращаемого значения содержат, соответственно, предыдущие x- и y-координаты начала физической системы координат.

Функция GetWindowOrg возвращает x- и y-координаты начала логической системы координат:

Новые функции, появившиеся в Windows версии 3.1, с именами GetViewportOrgEx и GetWindowExtEx записывают координаты начала координат в структуру, адрес которой передается через параметры lppt и lpSize:

Структура SIZE определена для Windows версии 3.1 и описана в файле windows.h следующим образом:

Определены также разнообразные указатели на структуру SIZE:

Метрические режимы отображения

Режим MM_LOMETRIC , наряду с режимами MM_HIMETRIC , MM_LOENGLISH , MM_HIENGLISH и MM_TWIPS, относится к метрическим режимам. Эти режимы отображения позволяют использовать привычные единицы измерения, такие как миллиметры и дюймы.

В метрических режимах отображения используются полные формулы преобразования координат, приведенные выше в разделе «Преобразование координат». В этих формулах приложение может изменять переменные, определяющие смещение начала физической или логической системы координат xViewOrg, yViewOrg, xWinOrg и yWinOrg.

Приложение не может изменить значения переменных xViewExt, yViewExt, xWinExt и yWinExt, от которых зависит масштаб по осям координат. Отношения xViewExt/xWinExt и yViewExt/yWinExt имеют фиксированное значение для каждого из метрических режимов отображения.

Заметим, что для этих режимов отношение yViewExt/yWinExt имеет отрицательный знак, в результате чего ось Y оказывается направленной снизу вверх.

Обратим ваше внимание на одно важное обстоятельство, связанное с использованием метрических режимов отображения.

Сразу после переключения в метрический режим отображения система координат примет достаточно странный вид (рис. 2.4).

Рис. 2.4. Ориентация осей сразу после переключения в метрический режим отображения

Ось X, как и следовало ожидать, окажется направленной слева направо, а ось Y — снизу вверх. Точка с координатами (0,0) будет находиться в верхнем левом углу экрана, поэтому для того чтобы нарисовать что-нибудь в такой системе координат, вам придется для y-координаты графических объектов использовать отрицательные числа. Для того чтобы система координат приняла более удобный вид, можно переместить начало физических координат в нижний левый угол окна или в центр окна.

Прежде, чем выполнять перемещение начала координат, следует определить размеры внутренней области окна. Это можно сделать при обработке сообщения WM_SIZE :

Для того чтобы расположить начало координат в левом нижнем углу окна, следует вызвать функцию SetViewportOrg, передав ей новые координаты начала физической системы координат (0,cyClient):

Полученная в результате система координат показана на рис. 2.5.

Рис. 2.5. Метрическая система координат, начало координат находится в левом нижнем углу окна

Аналогичным образом можно расположить начало системы координат в середине окна (рис. 2.6), обеспечив возможность использования положительных и отрицательных координат вдоль оси X и Y:

Рис. 2.6. Метрическая система координат, начало координат находится в центре окна

Режимы MM_ISOTROPIC и MM_ANISOTROPIC

Режимы отображения MM_ISOTROPIC (изотропный) и MM_ANISOTROPIC (анизотропный) допускают изменение направления осей X и Y, а также изменение масштаба осей координат. В изотропном режиме отображения MM_ISOTROPIC масштаб вдоль осей X и Y всегда одинаковый (т. е. для обоих осей используются одинаковые логические единицы длины). Анизотропный режим MM_ANISOTROPIC предполагает использование разных масштабов для разных осей (хотя можно использовать и одинаковые масштабы).

Для изменения ориентации и масштаба осей предназначены функции SetViewportExt, SetViewportExtEx, SetWindowExt и SetWindowExtEx.

Функция SetWindowExt устанавливает для формулы преобразования координат значения переменных xWinExt и yWinExt:

Функция SetViewportExt должна использоваться после функции SetWindowExt. Она устанавливает для формулы преобразования координат значения переменных xViewExt и yViewExt:

Обе функции возвращают в младшем и старшем слове предыдущие значения соответствующих переменных для оси X и Y.

Приведенные выше формулы можно использовать для установки отношений xViewExt/xWinExt и yViewExt/yWinExt, определяющих масштаб и направление осей координат (направление осей координат зависит от знака этих отношений).

Функции SetWindowExt передаются значения, соответствующие логическому размеру логического окна, в которое будет выполняться вывод, а функции SetViewportExt — реальные ширина и высота реального окна.

Например, нам надо создать систему координат, в которой начало отсчета расположено в левом нижнем углу окна, ось X направлена слева направо, а ось Y — снизу вверх. Высота и ширина должны изменяться от 0 до 32767 (максимально возможное значение, так как для координат используются 16-разрядные числа).

Если требуется получить одинаковый масштаб по осям X и Y, нужно использовать изотропный режим отображения MM_ISOTROPIC.

Приведем фрагмент кода, создающий необходимый режим отображения.

В изотропном режиме отображения при изменении размеров окна Windows настроит систему координат таким образом, чтобы масштаб по осям X и Y был одинаковый.

Если ширина окна больше высоты, масштаб по горизонтальной оси настраивается таким образом, что логическое окно будет расположено в левой части внутренней области окна (рис. 2.7).

Рис. 2.7. Изменение масштаба по горизонтали при увеличении ширины окна в изотропном режиме

Если же высота окна больше его ширины, при использовании изотропного режима отображения логическое окно окажется в нижней части внутренней области окна (рис. 2.8).

Рис. 2.8. Изменение масштаба по горизонтали при увеличении высоты окна в изотропном режиме

При использовании анизотропного режима отображения MM_ANISOTROPIC настройка масштаба не выполняется, поэтому логическое окно будет занимать всю внутреннюю поверхность окна при любом изменении размеров этого окна (рис. 2.9 и 2.10).

Рис. 2.9. Изменение масштаба по горизонтали при увеличении ширины окна в анизотропном режиме

Рис. 2.10. Изменение масштаба по горизонтали при увеличении высоты окна в анизотропном режиме

В программном интерфейсе Windows версии 3.1 есть новые функции, предназначенные для изменения масштабов осей. Это функции SetViewportExtEx и SetWindowExtEx :

От функций SetViewportExt и SetWindowExt эти функции отличаются тем, что старые значения переменных, определяющих масштаб преобразования, записываются в структуру SIZE, указатель на которую передается через параметр lpSize.

Изотропный режим отображения удобно использовать в тех случаях, когда надо сохранить установленное отношение масштабов осей X и Y при любом изменении размеров окна, в которое выводится изображение (рис. 2.7 и 2.8).

Анизотропный режим удобен в тех случаях, когда изображение должно занимать всю внутреннюю поверхность окна при любом изменении размеров окна. Соотношение масштабов при этом не сохраняется (рис. 2.9 и 2.10).

В этом разделе мы расскажем вам об использовании функций, предназначенных для рисования точек, линий, окружностей и других геометрических фигур.

Несмотря на то, что в программном интерфейсе GDI имеется функция SetPixel , позволяющая нарисовать один пиксел, не следует думать, что рисование линии или окружности сводится к многократному вызову этой функции. Если бы это было так, процесс рисования занимал бы очень много времени. На самом деле многие из функций рисования выполняются драйвером или даже аппаратурой видеоконтроллера, что значительно ускоряет вывод.

С помощью функции GetDeviceCaps приложение может определить, поддерживает ли драйвер ту или иную функцию рисования.

Первый параметр функции hdc задает контекст устройства, для которого необходимо получить информацию о его возможностях.

Второй параметр iCapability определяет параметр устройства, значение которого необходимо получить.

Приведем список значений для второго параметра функции GetDeviceCaps, с помощью которых можно определить, какие операции рисования выполняет драйвер устройства вывода.

Имя константы Описание
LINECAPS Способности устройства рисовать линии. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать линии различного типа:LC_INTERIORS устройство может закрашивать внутреннюю область;LC_MARKER маркеры;LC_NONE устройство не может рисовать линии;LC_POLYLINE ломаные линии;LC_POLYMARKER линии polymarker;LC_STYLED устройство может рисовать линии с использованием различных стилей (штриховые, пунктирные, штрих пунктирные и т.д.);LC_WIDE широкие линии;LC_WIDESTILED устройство может рисовать широкие линии с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)
CURVECAPS Способность устройства рисовать различные кривые линии и геометрические фигуры. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать различные фигуры:CC_CIRCLES окружности;CC_CHORD сегмент эллипса;CC_ELLIPSES эллипсы;CC_INTERIORS устройство может закрашивать внутреннюю область геометрических фигур;CC_NONE устройство не может рисовать кривые линии и геометрические фигуры;CC_PIE секторы эллипса;CC_ROUNDRECT прямоугольники со скругленными углами;CC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т.д.);CC_WIDE широкие рамки;CC_WIDESTYLED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)
POLYGONALCAPS Способности устройства рисовать многоугольники. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать многоугольники различного типа:PC_INTERIORS устройство может закрашивать внутреннюю область;PC_NONE устройство не может рисовать многоугольники;PC_RECTANGLE прямоугольники;PC_SCANLINES устройство может выполнять сканирование линий растра;PC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.);PC_WIDE широкие рамки;PC_WIDESTILED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)PC_WINDPOLYGON многоугольники с заполнением в режиме WINDING

Для приложения не имеет особого значения, кто именно будет рисовать — видеоконтроллер, драйвер или GDI. Запрос на рисование, например, эллипса, будет выполнен, даже если соответствующая операция не поддерживается драйвером. В последнем случае эллипс будет нарисован самим GDI с использованием более примитивных операций, но процесс рисования займет больше времени.

Учитывая сказанное выше, не следует строить работу приложений таким образом, чтобы периодичность вывода или скорость работы приложения зависела от скорости рисования (подобная практика не приветствуется и при создании программ для MS-DOS, вспомните, как ведут себя старые игры, разработанные для процессора 8088, на компьютерах с процессорами i80386 или i486). Современные видеоадаптеры сконструированы таким образом, что большинство основных операций рисования, используемых в операционной системе Windows, выполняются аппаратно. Эти видеоадаптеры иногда называются ускорителями Windows. Скорость рисования для ускорителя Windows может превышать в десятки раз скорость рисования для обычного адаптера VGA или SVGA.

Результат рисования геометрических фигур зависит от установки таких атрибутов контекста, как ширина, цвет и стиль линии (определяются выбранным в контекст отображения пером), способ закраски замкнутых фигур (определяется выбранной в контекст отображения кистью), цвета фона, прозрачностью фона (прозрачный режим TRANSPARENT и непрозрачный режим OPAQUE ), режимом рисования, режимом закрашивания, областью ограничения, режимом отображения, т. е. практически от всех атрибутов контекста отображения. Поэтому при описании функций мы будем попутно описывать способы изменения атрибутов контекста отображения, влияющих на результат их выполнения.

Работа с цветовыми палитрами и битовыми изображениями будут рассмотрены позже в отдельных разделах, так как эти вопросы далеко не тривиальны и поэтому заслуживают отдельного обсуждения.

Итак, перейдем непосредственно к описанию функций рисования геометрических фигур.

Рисование точки

Функция рисования точки SetPixel устанавливает цвет точки с заданными координатами:

Установка первых трех параметров этой функции не должна вызывать у вас никаких затруднений. Параметр hdc определяет контекст отображения, для которого необходимо изменить цвет точки. Параметры nXPos и nYPos определяют координаты точки в системе координат, которая зависит от установленного для контекста hdc режима отображения.

Последний параметр clrref определяет новый цвет точки. О том, как «раскрасить» окно приложения, вы узнаете из третьей главы нашей книги. Тем не менее мы опишем самый простой способ для функции SetPixel.

В файле windows.h есть описание макрокоманды RGB , позволяющей сконструировать цвет в формате COLORREF из отдельных компонент красного (r), зеленого (g) и голубого (b) цвета:

Вы можете использовать эту макрокоманду совместно с функцией SetPixel для установки, например, красного цвета точки, расположенной в начале системы координат (0,0), следующим образом:

Три параметра макрокоманды RGB позволяют задать любой из примерно 16 млн. цветов и оттенков, однако это не означает, что вы получите на экране точно такой цвет, какой был задан при помощи этой макрокоманды. Скорее всего вы сможете воспользоваться одним из 20 системных цветов. Причины этого вы узнаете в третьей главе. Там же мы расскажем о том, как в некоторых случаях можно расширить используемую гамму цветов.

Функция SetPixel возвращает цвет, который фактически был использован для рисования точки. Как мы только что заметили, возвращенное значение может отличаться от заданного параметром clrref. В случае ошибки оно будет равно -1.

Функция GetPixel позволяет узнать цвет точки, заданной идентификатором контекст

Веб-аналитика с помощью Google Tag Manager

Относительно недавно, мы проводили редизайн и оптимизацию нашего сайта и наткнулись на ряд проблем связанных со скриптами и кодами отслеживания от Google. А именно:

  • проблема избытка кода Google в коде страниц (отслеживание событий, Google A/B tests, Google Analytics)
  • неудобство управления и слежения за скриптами.
  • постоянная необходимость редактирования шаблонов страниц, для внесения изменений и дополнительных параметров в скрипты.
  • зависимость от релизов на поддоменах (индивидуальный случай). Например, над личным кабинетом работает не один человек, а команда разработки с использованием контроля версии (VSC) и для внесения малейших изменений приходилось ждать очередного релиза.

В данной статье мы рассмотрим решение данных проблем на примере Google Analytics, посредством Диспетчера тегов от Google (Google Tag Manager) и рассмотрим новую модель организации работы со скриптами, для анализа работы сайта с практическими примерами и кучей картинок.

Речь пойдет о Google Tag Manager (диспетчер тегов Google).

Основные преимущества перехода на диспетчер тегов на наш взгляд:

  • минимум кодинга на страницах. Убираем все скрипты от Google из кода страниц. Останется лишь код вставки Диспетчера тегов (код контейнера)
  • прозрачность и удобство. Удобство настройки и слежения за скриптами. Все управляется и настраивается из панели управления Диспетчера тегов. Мы видим все скрипты и к каким страницам и событиям они привязаны
  • масштабируемость. Больше не нужно затрагивать код страниц. Вы можете добавлять и настраивать код Google Analytics, отслеживания конверсий AdWords, ремаркетинга AdWords и много другого из личного кабинета диспетчера тегов.
  • система контроля версий. Любые изменения можно с легкостью отменить и вернуть на более ранний state, а так же следить за тем, кто, где и когда вносил изменения.
  • режим многопользовательской работы.

Также, если у вас имеется ресурс, который разрабатывается с использованием контроля версий и чтобы внести изменения в код страниц, приходится ждать очередного релиза, тогда Диспетчер тегов Google — это именно то, что вам нужно.

Немного теоретической части

Для быстрого старта, нам понадобиться разобрать основные термины, которые необходимы для начала работы с Google Tag Manager, а именно:

  • Аккаунт
  • Контейнер
  • Теги
  • Правила
  • Макросы

Эти термины будут встречаться как в статье, так и в любой документации от Google.

Аккаунт — это аккаунт=) как и в Google Analytics, в представлении не нуждается.

Контейнер — это главный и единственный фрагмент JS-кода, который мы вставляем на все страницы сайта. По сути, он является тегом, но его функция заключается в том, что он служит контейнером для всех тегов. О них написано чуть ниже. Своего рода «архитег», который запускает все остальные теги, при соответствии их правилам которые мы задали.

Тег — это фрагмент JS-кода. Все те скрипты, которые мы раньше вручную вставляли на страницы сайта, например, код Google Analytics, код отслеживания конверсий Adwords, пользовательский код и т.д.

Правило — это условие, при котором будет вызываться и выполняться тег или наоборот (блокироваться). Например, для кода Google Analytics правилом «выстрела» мы зададим: «на всех страницах».

Макросы — «Макросы являются парами типа имя/значение, для которых передаются значения в процессе работы». Используются при настройке правил. В нашем случае, переменные уровня данных для отслеживания событий (Event Tracking) в связке с целями Google Analytics, подробнее в практической части

Обобщим, в коде страницы имеется код контейнера. В контейнер с сервера Google подгружаются и активируются теги, которые соответствуют правилам активации. Макросы нужны для настройки тегов и правил.

Рис.1 Схема взаимодействия элементов

Практический пример

А теперь рассмотрим вышеперечисленное на простейшем примере с использованием основных возможностей.

У Google есть замечательный инструмент в виде плагина для Google Chrome — «Tag Assistant». Устанавливаем и вернемся к нему чуть позже.

Итак, предположим, имеется:

  • сайт — example.com
  • личный кабинет на поддомене — accounts.example.com

Необходимо:

  • разместить код Google Analytics
  • настроить отслеживание конверсии при клике на определенную кнопку

Регистрируем Google Analytics и Google диспетчер тегов.
В диспетчере тегов создаем аккаунт (рис.2).

Рис.2 Создание аккаунта

Далее создаем контейнер (рис.3). Указываем тип: «Веб-страницы» или «Мобильные приложения» и указываем наши домены(что, в принципе, необязательно). В нашем случае, поддомен мы не указываем, поскольку будем использовать междоменное отслеживание.

Рис.3 Создание контейнера

Готово! нам дают тот самый заветный код контейнера, который мы должны разместить сразу же после открывающего тега .

Код контейнера обязательно и всегда должен быть самым первым после открывающего тега , в противном случае вы рискуете потерять возможность отслеживания событий (Event Tracking) находящих ДО кода контейнера. Поскольку все переменные уровня данных, которые находятся до Диспетчера тегов, обрабатывать не будут.
Для большей гибкости и удобства — для основного домена и поддоменов лучше использовать разные контейнеры.

Там же — нам предлагают одним нажатием вставить теги. Выбираем тег «Google Analytics»(рис.4)

Рис.4 Код контейнера и меню выбора тегов

Далее, в окне настройки тега Google Analytics, нам нужно:

  1. ввести «идентификатор веб-ресурса» — это старый добрый код счетчика
  2. «добавить правило активации тега» — там ставим галочку напротив «все страницы». то есть код Google Analytics будет срабатывать на всех страницах сайта.
  3. так как у нас имеется поддомен — открываем вкладку
  4. «Дополнительные настройки» > «Домены и каталоги» и ставим галочку напротив «разрешить связывание» (это и есть междоменное отслеживание)

Рис.5 Настройка тега Google Analytics

С тегом Google Analytics закончили. Следующим этапом мы настроим макрос на отслеживание событий (Event Tracking). Нам понадобится создать 3 макроса, а потом на основе них — тег отслеживания.

Итого, у вас должно получиться 3 новых макроса с именами переменных уровня данных: eventCategory, eventAction, eventLabel. В качестве правила для активации, нам еще понадобиться макрос «event», но он уже создан по умолчанию.

Рис.6 Создание макроса

Далее создаем новый тег, выбираем тип тега — «Google Analytics», вставляем тот же код счетчика в поле идентификатора, а вот в типе отслеживания — выбираем «событие» и далее вставляем созданные нами макросы из списка, соответственно:

  • категория — GA Event Category
  • действие — GA Event Action
  • ярлык — GA Event Label

Рис.7 Создание тега отслеживания Google Analytics

Теперь нам нужно задать правило активации тега (рис.8). Создаем новое правило, в котором мы используем макрос «event»

Рис.8 Создание правила активации

Как это работает?

переменные уровня данных, у нас будут передаваться в таком виде:

Так как мы не хотим затрагивать код страниц, привязываем действие по клику с помощью jQuery и подключаем через Google Tag Manager(пользовательский тег), подобным образом:

Рис. 9 Добавляем пользовательский тег

То есть, при клике по объекту, мы будем передавать переменные уровня данных методом .push() и теми значениями, которые мы будем задавать в целях Google Analytics.

Итак, у нас вышло 4 наших макроса: «event», «eventCategory», «eventAction», «eventLabel»
и четыре пары значений:

  • ‘event’ : ’GAevent’
  • ‘eventCategory’ : ’value’
  • ‘eventAction’ : ’value’
  • ‘eventLabel’ : ’value’

Значения мы задаем в панели Google Analytics, в «настройках цели».

Чтобы нагляднее проследить взаимосвязь — см. рис.10

Рис. 10 Взаимосвязь переменных уровня данных, макросов и целей Google Analytics

Создаем цели в Google Analytics, вставляем переменные в наш метод dataLayer.push() для ссылки которую будем отслеживать.

Google Analytics добавили и настроили, макросы создали, добавили тег отслеживания, ОК. Переходим на вкладку «Общие сведения» — Создаем версию и публикуем (рис.11).

Рис. 11 Создание версии и публикация контейнера

Проверяем: перейдя на страницу сайта открываем «Tag Assistant», о котором говорилось в самом начале практической части.

Рис.12 окно Tag Assistant

Мы видим код нашего счетчика, код контейнера. Зеленый статус «working» говорит о том, что всё отличненько. В противном случае, он бы описал проблему и предложил рекомендации к ее решению. Также, мы видим наш Data Layer.(зачастую, данные dataLayer не отображаются в панели «tag assistant» и это норма).

Ну и так вот, на дорожку:
Рассмотренное в данной статье — лишь малая и простейшая часть того, что на самом деле представляет из себя Диспетчер тегов (Google Tag Manager) и какие возможности открываются перед нами при углублении во все нюансы.

Получение кода устройства, работающего на Andro >

Для полноценной работы программного обеспечения необходимо получить лицензию. Для получения лицензии нужно прислать на почту sales@cleverence.ru уникальный код устройства (Ид устройства).

Уникальный код устройства (Ид устройства) нужно знать только для ТСД, планшетов, смартфонов и микрокиосков.

Для мобильных принтеров и касс не нужно получать коды устройств, потому что лицензии привязываются не к кассе или мобильному принтеру, а к ТСД (смартфону, пларшету, киоску).

Получение кодов для другого вида оборудования смотрите в статье «Получение кода устройства».

Первый способ

  1. Запустите клиента на ТСД.
  2. Откройте выпадающее меню и выберите пункт «О приложении».

В открывшемся окне с информацией будет доступен код устройства (Ид устройства) в виде строки букв и цифр. Этот код не привязан к ПК, на котором выполнялась установка и не меняется при переустановках программного обеспечения.

20 шорткодов и плагинов WordPress, которые вы возможно захотите попробовать

Если вы не в курсе, что такое шорткоды WordPress, то уточню, что это коды, которые позволяют создавать различные креативные вещи с помощью скриптов и кода. Чтобы вам не приходилось вставлять в свои посты и страницы громоздкие и несуразные коды, они сжаты всего в одну строку -шорткод.

Если коротко, то шорткод, как правило, используется для быстрого вызова длинного сценария или фрагмента кода. Несмотря на то, что WordPress имеет свой собственный набор шорткодов, которые можно использовать в записях и страницах вашего блога, кроме них существует большое количество шорткодов, которые предлагают почти безграничные возможности.

Шорткоды можно вставлять в тему блога вручную или через плагин. Проблема состоит только в том, чтобы найти среди огромного их количества именно тот, который подойдет вам.

Не волнуйтесь, в этой статье, мы представим 10 плагинов для WordPress, которые добавляют в ваш блог функциональный шорткод, а также 10 кодов, которые можно добавить самостоятельно.

Плагины WordPress

Вот некоторые из плагинов, которые позволяют применять или настраивать шорткоды WordPress. В соответствующих случаях предлагается альтернативный плагин, который делает почти то же самое.

1. Shortcode

Простой плагин, который добавляет несколько полезных шорткодов , предназначенных для отображения количественных характеристик вашего блога:

[ postcountbr ] — отображает общее количество опубликованных в блоге записей;
[ catcountbr ] — отображает общее количество категорий, которые содержат одну или более запись;
[ tagcountbr ] — отображает общее количество тегов, которые содержатся в одной или более записи;
[ totalwords ] — отображает общее количество слов в опубликованных записях;
[ commentcount ] — отображает общее число одобренных комментариев;
[ PageCount ] — отображает общее количество опубликованных страниц.

2. WordPress Shortcodes

Этот плагин включает в себя более 20 шорткодов WordPress и простой редактор шорткодов.

Вы можете использовать его для добавления в свой блог таких крутых элементов, как:

  • SEO-ready вкладки, кнопки;
  • Карточки авторов;
  • Окна сообщений;
  • Смарт-ссылки;
  • Разделы;
  • Списки и т.д.

Вы можете даже объединять несколько встроенных шорткодов, чтобы создавать такие уникальные элементы, как список кнопок или ссылок.

Другие варианты : Существует два аналогичных плагина J Shortcodes и Arconix Shortcodes — которые также включают в себя набор полезных шорткодов. Например, для создания контента и информационных панелей, кнопок, вкладок, выпадающих панелей, переключателей и многого другого.

3. Post Content Shortcodes

Этот плагин добавляет в блог два шорткода:

[post-content] — позволяет отображать содержимое одиночной записи или страницы, внутри другой записи или страницы. Вы должны использовать в шорткоде аргумент, чтобы указать ID поста. Вы также можете использовать аргументы, чтобы отображать характерное изображение, фрагмент записи и заголовок поста;

[post-list] — отображает список записей внутри другой записи. Этот шорткод также поддерживает опциональные аргументы для настройки списков: опции упорядочения элементов, типы/статусы сообщений, вывод изображений и т.д. Вы даже можете подтянуть список записей из другого блога, добавив ID блога в качестве аргумента в шорткод.

4. Shortcoder

Плагин Shortcoder позволяет создавать пользовательские шорткоды через визуальный редактор. Вы также можете хранить часто используемые тексты, HTML и фрагменты JavaScript.

Плагин имеет встроенную кнопку TinyMCE, которую можно использовать в редакторе блога, чтобы вставлять шорткоды. Это позволит вам добавлять свои собственные шорткоды:

Другие варианты : Если вы ищете нечто подобное, попробуйте плагин Shortcode Manager, который позволяет создавать, управлять, импортировать и экспортировать шорткоды.

5. Hide Broken Shortcodes

Иногда, вы можете отключить шорткод, случайно оставив часть его функционала. Вместо того чтобы перебирать каждую страницу или запись, чтобы удалить « битые » шорткоды, проще будет скрыть их. Данный плагин поможет вам это сделать.

Другие варианты : Hide Unwanted Shortcodes аналогичный плагин, который делает «битые» шорткоды недоступными для просмотра на сайте. После этого вы можете отредактировать шорткод на странице настроек плагина.

6. Column Shortcodes

Если вам нужен простой способ создания столбцов внутри ваших сообщений и страниц — это идеальный шорткод-плагин. Просто выберите нужную ширину столбца из всплывающего окна плагина, и он будет добавлен в редактор сообщения.

На выбор предлагается 10 размеров столбцов: от одной шестой до всей ширины страницы. Вы также можете настроить заполнение каждого отдельного столбца:

7. Metaphor Shortcodes

Если вы хотите использовать для ваших сообщений и страниц адаптивную сетку столбцов, попробуйте плагин Metaphor Shortcodes. С его помощью вы можете установить определенные параметры для столбцов: такие как интервал, начало, конец и классы.

Этот плагин также поддерживает несколько других удобных шорткодов, в том числе:

  • Post Block Shortcode — отображает название и выдержку из любого типа сообщений в любом месте вашего блога;
  • Post Slider Shortcode — создает горизонтальный слайдер для любого типа сообщений и выводит его в контенте блога;
  • Pricing Table Shortcode — создает различные типы таблиц прайсов для отображения в контенте вашего блога.

8. ShortCodes UI

ShortCodes UI это еще один плагин для создания шорткодов, которые используют собственные кнопки TinyMCE и Quicktag. Вы можете легко вставлять шорткоды в ваши сообщения и страницы через визуальный и HTML редакторы.

Данный плагин отлично подходит для новичков, которые плохо знакомы с кодами, для них предназначены обучающие видеоуроки. Те, кто знает о кодах немного больше, вероятно, оценят цветовую разметку синтаксиса в редакторе кода.

Присутствует также функция импорта / экспорта, с помощью которой вы можете переместить ваши шорткоды с одного сайта на другой и даже поделиться с друзьями.

Другие варианты : My Shortcodes — это аналогичный плагин с красивым интерфейсом, который позволяет создавать собственные шорткоды.

В административной панели плагина, вы можете управлять, редактировать, включать / выключать, а также экспортировать элементы и шорткоды. Интерактивный просмотр позволяет увидеть, как выглядит ваш шорткод еще до его добавления в запись или на страницу.

9. Last Updated Shortcode

Это очень простой плагин, который позволяет добавить шорткод [ LastUpdated ] в ваши записи и страницы. Данная функция будет отображать дату и / или время последнего обновления.

Есть также опции для изменения формата отображения даты / времени.

10. Geoportail Shortcode

Данный плагин добавляет с помощью шорткода карту Geoportail в ваши сообщения и страницы. После этого вы можете задать размер карты, масштаб, местоположение (широту и долготу), размер (обычный, мини), территорию, слои и многое другое.

Карта поддерживает геотеги (которые можно подключить через плагин Геолокации ), чтобы в блоге отображалось место написания (публикации) ваших сообщений.

Плагин также включает в себя шорткод-билдер, для настройки шорткода карты, а также функцию предварительного просмотра, с помощью которой вы сможете просмотреть вашу карту, прежде чем публиковать ее.

Шорткоды

Существуют также простые шорткоды, которые можно использовать в блоге — без необходимости устанавливать их через плагин.

Для каждого шорткода мы предоставим вам:

  • Тело шорткода — длинный кусок кода, который должен быть вставлен в файл функций темы (functions.php) вашего блога, вставка осуществляется через «Редактор», доступный в панели инструментов WordPress (Дизайн > Редактор);
  • Шорткод , который может быть размещен в любом месте вашей записи или страницы, через него подключается функционал.

Для некоторых шорткодов, возможно, потребуется дополнительная настройка (например, добавление вашего личного кода Google AdSense), так что некоторые знания о редактировании кодов вам все же понадобятся.

Другие шорткоды могут иметь дополнительные параметры, которые вы можете добавить: например, ширина и высота. Узнать больше вы можете кликнув ссылку для каждого шорткода.

Insert AdSense Ads

Вставляет блок объявления Google AdSense в том месте вашего контента, где вам нужно.

Выводит список похожих записей выше или ниже контента страницы.

Добавляет кнопку PayPal, с помощью которой пользователи могут удобно для себя сделать пожертвование.

Display A Google Map

Добавляет Google Map в любом месте вашей записи.

Шорткод : [googlemap src=»google_map_url»]

Display External Files

Вставляет дополнительные файлы, такие как текст и изображения, в ваши сообщения.

Шорткод : [show_file file=»http://www.test.com/test.html»]

Add A Login Form

Добавляет форму авторизации в ваши записи и страницы, не только в сайдбаре.

Display Private Notes

Добавляет приватные пометки в ваши записи или страницы, они будут видны только администратору.

Шорткод : [note]Your Note Here[/note]

Registered Users Only Content

Добавляет контент, который смогут видеть только зарегистрированные пользователи.

Шорткод : [member]For Registered Users Only[/member]

Embed YouTube Videos

Шорткод позволяет вставлять не только видео с YouTube, но и может быть использован для вставки других мультимедийных материалов, таких как аудио и изображения.

Obfuscate Email Address

Защищает вашу электронную почту от спамеров, делая невозможным ее копирование со страницы.

Шорткод : [email address=»you@email.com»]

Данная публикация представляет собой перевод статьи « 20 WordPress Shortcodes And Plugins You Might Want To Try » , подготовленной дружной командой проекта Интернет-технологии.ру

Что такое код getviewportorg

Верификация — это процесс подтверждения права вашей собственности на сайт или приложение. Компания Google должна получить такое подтверждение, чтобы дать вам доступ к данным сайта в Google Поиске и возможность изменять настройки его сканирования.

Верификация сайта — это один из шагов, который нужно выполнить при использовании Search Console . Search Console — это бесплатный сервис от Google, который позволяет узнать, как ваш сайт представлен в Google Поиске, и при необходимости оптимизировать его. Вам необязательно регистрироваться в этом сервисе, чтобы ваш сайт попал в выдачу Google. Однако это позволит узнать, как Google воспринимает сайт, и принять меры для улучшения его позиции в результатах поиска.

Как получить ID для верификации через Google?

  1. Откройте сайт Search Console от Google: https://search.google.com/search-console/welcome и вставьте HTTPS-версию своего домена «www».
  2. Нажмите на серую кнопку «Add Property».
  3. В разделе «Other verification methods» выберите «HTML tag».
  4. У вас появится доступ к >
  5. Вставьте этот код в личный кабинет WebDirect, следуя инструкциям ниже.

Как вставить ID для верификации через Google в личный кабинет?

Чтобы верифицировать сайт WebDirect через Search Console от Google:

  1. Войдите в личный кабинет в раздел «Настройки» >«Менеджер меток» .
  2. Нажмите на желтую кнопку «Новая метка» и выберите «Верификация через Google» («Google Site Verification») .
  3. Вставьте свой ID для верификации .
  4. Нажмите «Сохранить» , а затем «Опубликовать» .
  5. Затем вернитесь на страницу Search Console от Google и нажмите на серую кнопку «Verify» .

Что такое GLN и зачем он нужен поставщику торговой сети

Когда компания обращается к провайдеру электронного документооборота для подключения к сервисам EDI и ЭДО, ей необходимо получить специальный идентификационный номер – GLN.

Не стоит относиться к этому как лишней формальности. Кроме своего прямого назначения, GLN открывает несколько любопытных возможностей.

Что такое GLN

В двух словах: GLN (Global Location Number) переводится как Глобальный номер места нахождения или Глобальный идентификационный номер. Это специальный международный код, применяемый в системах электронного обмена данными и электронной коммерции. С его с помощью можно точно и кратко определить расположение юридических лиц, их функциональных подразделений и физических объектов – складов, магазинов, производственных помещений, транспортных единиц.

Номер состоит из 13 цифр. Начинается с двух- или трёхзначного национального префикса (в России – с 460 до 469), а заканчивается контрольным числом. Основное требование к GLN – его уникальность. Код, присвоенный какому-либо предприятию, не должен повторяться нигде.

Поскольку EDI работает по достаточно жёстким стандартам, без GLN электронный обмен данными невозможен. Это ключевая концепция EDI. И в России, и в Бразилии, и в Финляндии компании идентифицируются по GLN. Отчасти аналогом GLN в России можно назвать ОКПО, ОКВЭД, БИК, ИНН и прочие. Все они призваны идентифицировать предприятия среди сотен тысяч других. Но поскольку в каждой стране приняты свои системы кодирования, при подготовке международных коммерческих документов нужно использовать единый формат. GLN решает проблему как универсальный способ идентификации.

Сегодня GLN поддерживается международной ассоциацией GS1, ведающей вопросами стандартизации учёта и штрихового кодирования логистических единиц. У ассоциации есть представительство в России.

Зачем нужен GLN

При бумажном документообороте, сопровождающем цепочки поставок, для каждой сделки в договорах и счетах требуется указывать имена, адреса, реквизиты сторон коммерческих сделок – покупателя, перевозчика, продавца. Это занимает определенное пространство на бумаге, чревато ошибками и требует постоянного поддержания всей рабочей документации в актуальном состоянии.

В электронном документообороте, особенно при прямом взаимодействии между ERP, рабочими станциями и информационными системами разных деловых партнёров, достаточно указать только номер GLN. Используя его, можно автоматически извлечь всю необходимую информацию. Данные, доступ которым открывается по номеру GLN, хранятся партнёрами во внутренних системах и в глобальном реестре. Обновление происходит централизовано.

С помощью GLN происходит идентификация объектов как внутри, так и за пределами компании. По этому номеру можно получить данные о типе объекта (производственный центр, склад, торговый офис, офис компании), регионе, почтовом адресе, контактных данных и лицах, банковских реквизитах, требованиях и ограничениях доставки и т. д.

Если взять правила присвоения номеров GLN, то можно увидеть четыре основных случая их использования для идентификации:

  • для определения юридического лица
  • для фактического нахождения объекта
  • для определения функции объекта
  • для цифрового места нахождения.

Когда компании нужно идентифицировать отдельные объекты в цепочках поставок, то для каждого их них (например, распределительных центров в разных регионах) заводится отдельный GLN. Таким образом, партнёры смогут отличить один РЦ от другого при электронном документообороте.

Более того, GLN позволяет определять не только расположение объектов, но и отдельные части этих мест – этажи, помещения, определённые места на полках, дворы рядом со зданиями, причалы в порту и т. п.

Используя специальные компоненты расширения номера, можно даже не заводить отдельный GLN и для разных стеллажей на складе использовать один GLN (в виде GLN+x, GLN+y, GLN+z). Это особенно востребованно для решений по управлению и слежению за товарными запасами. Такие уточнения к номерам дают возможность организовать наглядное представление о ситуации. Например, указание взять партию товара с номером GLN+x и отправить на номер GLN+z – значит забрать товар с определённого места на складе и выставить на конкретную полку в нужном магазине.

Но когда организации разрастаются или их структура становится более сложной, использование одного номера GLN может создавать нежелательные зависимости и трудности. При необходимости, следует заводить отдельные номера GLN.

Если одна компания выполняет сразу несколько отличающихся функций (например, занимается 3PL-логистикой и ритейлом), то номера можно закрепить за соответствующими подразделениями или отделами в составе организации. Ведь торговым партнерам необходимо отличать одну функцию от других (сбыт, логистику, бухгалтерию).

Например, три отдела одной компании могут использовать три разных номера GLN, чтобы они могли взаимодействовать с внешними контрагентами, а остальные – один общий, если для них не стоит задачи отдельной идентификации. Это также актуально для холдингов со сложной разветвлённой структурой, когда за логистику, документооборот и продажи отвечают разные юрлица, аффилированные между собой.

В случае с цифровым местонахождением, GLN фиксирует электронный адрес, использующийся для связи между компьютерными системами. Это необходимо, если цифровые контакты (шлюз EDI, банк данных, система ERP, система управления складом и т. д.) непосредственно участвуют в транзакциях и их нужно отдельно идентифицировать.

Чтобы считать информацию из GLN, номера кодируются либо штрих-кодом, либо метками EPC / RFID для автоматической идентификации мест хранения, назначения паллет, происхождения продукта и т. д. Это позволяет проводить более эффективную работу по отгрузке и приёмке товара.

Как получить GLN

Если компания-поставщик собирается перейти на электронный обмен данными с торговой сетью, то ритейлер её обяжет получить GLN. Как правило, этот этап идёт следующим после заключения договора и даже до этапа сверки товарного ассортимента (например, такие правила есть у «Магнита» и X5 Retail Group)

Часто на этапе тестирования EDI-обмена можно использовать, так называемый, «фейковый» GLN, создаваемый бесплатно. Но для продуктивной работы потребуется получить официальный номер.

Услуги по внесению информации о предприятии в международную систему GS1 в России через EDI-провайдеров будут стоить около 3 тысяч рублей за один год. Компания может сэкономить, если, к примеру, зарезервирует номер сразу на три года. Это обойдётся, в среднем, в 6 – 6,5 тысяч рублей.

Альтернативный вариант – вступить в саму ассоциацию GS1, члены который могут получить необходимые номера бесплатно. Но здесь главным ограничением является размер вступительных и ежегодных взносов (в сумме – 40 тысяч рублей).

Коротко

А теперь подведём короткий итог о том, что нужно знать и понимать про номер GLN:

  • GLN используется во всем мире, в том числе и в России. Это общепринятый стандарт. Он избавляет от необходимости каждый раз вносить в документы реквизиты и контактные данные.
  • Номер нужно получить обязательно, это один из основных принципов электронного документооборота. Чтобы сэкономить, регистрируйте номера сразу на несколько лет вперёд.
  • С помощью GLN можно идентифицировать любую часть предприятия, отдельные функции компании, филиалы, даже рампу на складе или полку в магазине, если они участвуют в качестве самостоятельного объекта в цепочке поставок. Ваш контрагент будет знать куда привозить товар, а вы – откуда его отгружать.
  • Для схожих объектов мелкого порядка – рядов стеллажей в распределительном центре – можно завести один номер со специальными расширениями. Если структура цепочки поставок сложная и разветвлённая – лучше использовать отдельные GLN.
Илон Маск рекомендует:  Работа с Cookie. Java Script
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL